1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2016 Intel Corporation. All rights reserved. 39e3d841dSEvgeniy Kochetov * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved. 497385af1SAlexey Marchuk * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 503788f93SBen Walker */ 603788f93SBen Walker 7a36785dfSDennis Maisenbacher #include "spdk/bdev_zone.h" 8a36785dfSDennis Maisenbacher #include "spdk/nvme_spec.h" 903788f93SBen Walker #include "spdk/stdinc.h" 1003788f93SBen Walker 11ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h" 122d630f9bSDaniel Verkamp #include "spdk_internal/mock.h" 135fc0475cSJiewei Ke #include "thread/thread_internal.h" 1403788f93SBen Walker 1506a0d9abSBen Walker #include "common/lib/ut_multithread.c" 1629eb9567SJim Harris #include "nvmf/ctrlr.c" 1703788f93SBen Walker 182172c432STomasz Zawadzki SPDK_LOG_REGISTER_COMPONENT(nvmf) 1903788f93SBen Walker 205c2952abSDaniel Verkamp struct spdk_bdev { 215c2952abSDaniel Verkamp int ut_mock; 22a35b1eb6SDaniel Verkamp uint64_t blockcnt; 235818b42fSmatthewb uint32_t blocklen; 24a36785dfSDennis Maisenbacher bool zoned; 25a36785dfSDennis Maisenbacher uint32_t zone_size; 26a36785dfSDennis Maisenbacher uint32_t max_open_zones; 27a36785dfSDennis Maisenbacher uint32_t max_active_zones; 285e4d957eSShuhei Matsumoto enum spdk_dif_type dif_type; 295c2952abSDaniel Verkamp }; 3003788f93SBen Walker 3143d3da2eSSlawomir Ptak #define MAX_OPEN_ZONES 12 3243d3da2eSSlawomir Ptak #define MAX_ACTIVE_ZONES 34 3343d3da2eSSlawomir Ptak #define ZONE_SIZE 56 34a36785dfSDennis Maisenbacher 35225c74e4SAlexey Marchuk const char subsystem_default_sn[SPDK_NVME_CTRLR_SN_LEN + 1] = "subsys_default_sn"; 36225c74e4SAlexey Marchuk const char subsystem_default_mn[SPDK_NVME_CTRLR_MN_LEN + 1] = "subsys_default_mn"; 37225c74e4SAlexey Marchuk 385818b42fSmatthewb static struct spdk_bdev_io *zcopy_start_bdev_io_read = (struct spdk_bdev_io *) 0x1122334455667788UL; 395818b42fSmatthewb static struct spdk_bdev_io *zcopy_start_bdev_io_write = (struct spdk_bdev_io *) 405818b42fSmatthewb 0x8877665544332211UL; 415818b42fSmatthewb static struct spdk_bdev_io *zcopy_start_bdev_io_fail = (struct spdk_bdev_io *) 0xFFFFFFFFFFFFFFFFUL; 425818b42fSmatthewb 432d630f9bSDaniel Verkamp DEFINE_STUB(spdk_nvmf_tgt_find_subsystem, 442d630f9bSDaniel Verkamp struct spdk_nvmf_subsystem *, 452d630f9bSDaniel Verkamp (struct spdk_nvmf_tgt *tgt, const char *subnqn), 4660232f67SDaniel Verkamp NULL); 4703788f93SBen Walker 482d630f9bSDaniel Verkamp DEFINE_STUB(spdk_nvmf_poll_group_create, 492d630f9bSDaniel Verkamp struct spdk_nvmf_poll_group *, 502d630f9bSDaniel Verkamp (struct spdk_nvmf_tgt *tgt), 5160232f67SDaniel Verkamp NULL); 52a4e28342SBen Walker 532d630f9bSDaniel Verkamp DEFINE_STUB(spdk_nvmf_subsystem_get_sn, 542d630f9bSDaniel Verkamp const char *, 552d630f9bSDaniel Verkamp (const struct spdk_nvmf_subsystem *subsystem), 56225c74e4SAlexey Marchuk subsystem_default_sn); 572d1a2926SDaniel Verkamp 5814032a98SGregory Shapiro DEFINE_STUB(spdk_nvmf_subsystem_get_mn, 5914032a98SGregory Shapiro const char *, 6014032a98SGregory Shapiro (const struct spdk_nvmf_subsystem *subsystem), 61225c74e4SAlexey Marchuk subsystem_default_mn); 6214032a98SGregory Shapiro 632d630f9bSDaniel Verkamp DEFINE_STUB(spdk_nvmf_subsystem_host_allowed, 642d630f9bSDaniel Verkamp bool, 652d630f9bSDaniel Verkamp (struct spdk_nvmf_subsystem *subsystem, const char *hostnqn), 6660232f67SDaniel Verkamp true); 674ff0eba8SDaniel Verkamp 689cb21ad6SSeth Howell DEFINE_STUB(nvmf_subsystem_add_ctrlr, 692d630f9bSDaniel Verkamp int, 702d630f9bSDaniel Verkamp (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr), 7160232f67SDaniel Verkamp 0); 7221ea2901SBen Walker 739cb21ad6SSeth Howell DEFINE_STUB(nvmf_subsystem_get_ctrlr, 742d630f9bSDaniel Verkamp struct spdk_nvmf_ctrlr *, 752d630f9bSDaniel Verkamp (struct spdk_nvmf_subsystem *subsystem, uint16_t cntlid), 7660232f67SDaniel Verkamp NULL); 77415a0d2bSKonrad Sztyber DEFINE_STUB(nvmf_subsystem_zone_append_supported, bool, 78415a0d2bSKonrad Sztyber (struct spdk_nvmf_subsystem *subsystem), false); 799cb21ad6SSeth Howell DEFINE_STUB(nvmf_ctrlr_dsm_supported, 802d630f9bSDaniel Verkamp bool, 812d630f9bSDaniel Verkamp (struct spdk_nvmf_ctrlr *ctrlr), 8260232f67SDaniel Verkamp false); 83bf6caa75SDaniel Verkamp 849cb21ad6SSeth Howell DEFINE_STUB(nvmf_ctrlr_write_zeroes_supported, 852d630f9bSDaniel Verkamp bool, 862d630f9bSDaniel Verkamp (struct spdk_nvmf_ctrlr *ctrlr), 8760232f67SDaniel Verkamp false); 880caab4e1SDaniel Verkamp 898305e49bSEvgeniy Kochetov DEFINE_STUB(nvmf_ctrlr_copy_supported, 908305e49bSEvgeniy Kochetov bool, 918305e49bSEvgeniy Kochetov (struct spdk_nvmf_ctrlr *ctrlr), 928305e49bSEvgeniy Kochetov false); 938305e49bSEvgeniy Kochetov 949cb21ad6SSeth Howell DEFINE_STUB_V(nvmf_get_discovery_log_page, 953fe30060SChangpeng Liu (struct spdk_nvmf_tgt *tgt, const char *hostnqn, struct iovec *iov, 963d8904c6SAlexey Marchuk uint32_t iovcnt, uint64_t offset, uint32_t length, struct spdk_nvme_transport_id *cmd_src_trid)); 9703788f93SBen Walker 986dbcb893SBen Walker DEFINE_STUB(spdk_nvmf_qpair_get_listen_trid, 996dbcb893SBen Walker int, 1006dbcb893SBen Walker (struct spdk_nvmf_qpair *qpair, struct spdk_nvme_transport_id *trid), 1016dbcb893SBen Walker 0); 1026dbcb893SBen Walker 1036dbcb893SBen Walker DEFINE_STUB(spdk_nvmf_subsystem_listener_allowed, 1046dbcb893SBen Walker bool, 1056913a864SJacek Kalwas (struct spdk_nvmf_subsystem *subsystem, const struct spdk_nvme_transport_id *trid), 1066dbcb893SBen Walker true); 1076dbcb893SBen Walker 1087bcff376SShuhei Matsumoto DEFINE_STUB(nvmf_subsystem_find_listener, 1097bcff376SShuhei Matsumoto struct spdk_nvmf_subsystem_listener *, 1107bcff376SShuhei Matsumoto (struct spdk_nvmf_subsystem *subsystem, 1117bcff376SShuhei Matsumoto const struct spdk_nvme_transport_id *trid), 1127bcff376SShuhei Matsumoto (void *)0x1); 1137bcff376SShuhei Matsumoto 1149cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_read_cmd, 1151b6b6cc4SBen Walker int, 1161b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1171b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1181b6b6cc4SBen Walker 0); 1191b6b6cc4SBen Walker 1209cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_write_cmd, 1211b6b6cc4SBen Walker int, 1221b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1231b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1241b6b6cc4SBen Walker 0); 1251b6b6cc4SBen Walker 1269cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_compare_cmd, 127941d9e7aSMaciej Szwed int, 128941d9e7aSMaciej Szwed (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 129941d9e7aSMaciej Szwed struct spdk_nvmf_request *req), 130941d9e7aSMaciej Szwed 0); 131941d9e7aSMaciej Szwed 1329cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_compare_and_write_cmd, 13371beb568SMaciej Szwed int, 13471beb568SMaciej Szwed (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 13571beb568SMaciej Szwed struct spdk_nvmf_request *cmp_req, struct spdk_nvmf_request *write_req), 13671beb568SMaciej Szwed 0); 13771beb568SMaciej Szwed 1389cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_write_zeroes_cmd, 1391b6b6cc4SBen Walker int, 1401b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1411b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1421b6b6cc4SBen Walker 0); 1431b6b6cc4SBen Walker 1449cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_flush_cmd, 1451b6b6cc4SBen Walker int, 1461b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1471b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1481b6b6cc4SBen Walker 0); 1491b6b6cc4SBen Walker 1509cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_dsm_cmd, 1511b6b6cc4SBen Walker int, 1521b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1531b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1541b6b6cc4SBen Walker 0); 1551b6b6cc4SBen Walker 1568305e49bSEvgeniy Kochetov DEFINE_STUB(nvmf_bdev_ctrlr_copy_cmd, 1578305e49bSEvgeniy Kochetov int, 1588305e49bSEvgeniy Kochetov (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1598305e49bSEvgeniy Kochetov struct spdk_nvmf_request *req), 1608305e49bSEvgeniy Kochetov 0); 1618305e49bSEvgeniy Kochetov 1629cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_nvme_passthru_io, 1631b6b6cc4SBen Walker int, 1641b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1651b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1661b6b6cc4SBen Walker 0); 1671b6b6cc4SBen Walker 16861d85773SSeth Howell DEFINE_STUB(nvmf_transport_req_complete, 169a4d666fdSBen Walker int, 170a4d666fdSBen Walker (struct spdk_nvmf_request *req), 171a4d666fdSBen Walker 0); 172a4d666fdSBen Walker 1739cb21ad6SSeth Howell DEFINE_STUB_V(nvmf_ns_reservation_request, (void *ctx)); 174bc1d0b91SChangpeng Liu 1759cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_get_dif_ctx, bool, 176b09de013SShuhei Matsumoto (struct spdk_bdev_desc *desc, struct spdk_nvme_cmd *cmd, 177ddb680ebSShuhei Matsumoto struct spdk_dif_ctx *dif_ctx), 178ddb680ebSShuhei Matsumoto true); 179ddb680ebSShuhei Matsumoto 180604b4503SShuhei Matsumoto DEFINE_STUB_V(nvmf_transport_qpair_abort_request, 181604b4503SShuhei Matsumoto (struct spdk_nvmf_qpair *qpair, struct spdk_nvmf_request *req)); 182604b4503SShuhei Matsumoto 183afefd815SJacek Kalwas DEFINE_STUB_V(spdk_nvme_print_command, (uint16_t qid, struct spdk_nvme_cmd *cmd)); 18481717da1SJacek Kalwas DEFINE_STUB_V(spdk_nvme_print_completion, (uint16_t qid, struct spdk_nvme_cpl *cpl)); 185afefd815SJacek Kalwas 1863b461269SNick Connolly DEFINE_STUB_V(nvmf_subsystem_remove_ctrlr, (struct spdk_nvmf_subsystem *subsystem, 1873b461269SNick Connolly struct spdk_nvmf_ctrlr *ctrlr)); 1883b461269SNick Connolly 1893b461269SNick Connolly DEFINE_STUB(spdk_nvmf_bdev_ctrlr_abort_cmd, 1903b461269SNick Connolly int, 1913b461269SNick Connolly (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1923b461269SNick Connolly struct spdk_nvmf_request *req, struct spdk_nvmf_request *req_to_abort), 1933b461269SNick Connolly 0); 1943b461269SNick Connolly 1953b461269SNick Connolly DEFINE_STUB(nvmf_transport_req_free, 1963b461269SNick Connolly int, 1973b461269SNick Connolly (struct spdk_nvmf_request *req), 1983b461269SNick Connolly 0); 1993b461269SNick Connolly 2003b461269SNick Connolly DEFINE_STUB(spdk_nvmf_bdev_ctrlr_nvme_passthru_admin, 2013b461269SNick Connolly int, 2023b461269SNick Connolly (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 2033b461269SNick Connolly struct spdk_nvmf_request *req, spdk_nvmf_nvme_passthru_cmd_cb cb_fn), 2043b461269SNick Connolly 0); 205f63c0899SChangpeng Liu DEFINE_STUB(spdk_bdev_reset, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 206f63c0899SChangpeng Liu spdk_bdev_io_completion_cb cb, void *cb_arg), 0); 207f63c0899SChangpeng Liu DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io)); 2083b461269SNick Connolly 209a36785dfSDennis Maisenbacher DEFINE_STUB(spdk_bdev_get_max_active_zones, uint32_t, (const struct spdk_bdev *bdev), 210a36785dfSDennis Maisenbacher MAX_ACTIVE_ZONES); 211a36785dfSDennis Maisenbacher DEFINE_STUB(spdk_bdev_get_max_open_zones, uint32_t, (const struct spdk_bdev *bdev), MAX_OPEN_ZONES); 212a36785dfSDennis Maisenbacher DEFINE_STUB(spdk_bdev_get_zone_size, uint64_t, (const struct spdk_bdev *bdev), ZONE_SIZE); 213a36785dfSDennis Maisenbacher DEFINE_STUB(spdk_bdev_is_zoned, bool, (const struct spdk_bdev *bdev), false); 214a36785dfSDennis Maisenbacher 2157bbeb80aSAnkit Kumar DEFINE_STUB(spdk_nvme_ns_get_format_index, uint32_t, 2167bbeb80aSAnkit Kumar (const struct spdk_nvme_ns_data *nsdata), 0); 2177bbeb80aSAnkit Kumar 2187efdf905SSlawomir Ptak DEFINE_STUB(spdk_nvmf_subsystem_is_discovery, bool, (struct spdk_nvmf_subsystem *subsystem), false); 2190a6bb8caSKonrad Sztyber DEFINE_STUB(nvmf_subsystem_host_auth_required, bool, (struct spdk_nvmf_subsystem *s, const char *n), 2200a6bb8caSKonrad Sztyber false); 2210a6bb8caSKonrad Sztyber DEFINE_STUB(nvmf_qpair_auth_init, int, (struct spdk_nvmf_qpair *q), 0); 2220a6bb8caSKonrad Sztyber DEFINE_STUB(nvmf_auth_request_exec, int, (struct spdk_nvmf_request *r), 2230a6bb8caSKonrad Sztyber SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 2247efdf905SSlawomir Ptak 225ea1a6608SJim Harris DEFINE_STUB(spdk_nvmf_subsystem_get_nqn, const char *, 226ea1a6608SJim Harris (const struct spdk_nvmf_subsystem *subsystem), NULL); 227ea1a6608SJim Harris 22805632afdSAtul Malakar DEFINE_STUB(spdk_bdev_io_type_supported, bool, 22905632afdSAtul Malakar (struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type), false); 23005632afdSAtul Malakar 231db221b40SKonrad Sztyber void 232db221b40SKonrad Sztyber nvmf_qpair_set_state(struct spdk_nvmf_qpair *qpair, enum spdk_nvmf_qpair_state state) 233db221b40SKonrad Sztyber { 234db221b40SKonrad Sztyber qpair->state = state; 235db221b40SKonrad Sztyber } 236db221b40SKonrad Sztyber 237b8769cdbSJinYu int 238608b54a2SKonrad Sztyber spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair) 239b8769cdbSJinYu { 240b8769cdbSJinYu return 0; 241b8769cdbSJinYu } 242b8769cdbSJinYu 243ddda03efSPiotr Pelplinski void 2449cb21ad6SSeth Howell nvmf_bdev_ctrlr_identify_ns(struct spdk_nvmf_ns *ns, struct spdk_nvme_ns_data *nsdata, 2451c7f92f0SShuhei Matsumoto bool dif_insert_or_strip) 246a35b1eb6SDaniel Verkamp { 247a35b1eb6SDaniel Verkamp uint64_t num_blocks; 248a35b1eb6SDaniel Verkamp 249a35b1eb6SDaniel Verkamp SPDK_CU_ASSERT_FATAL(ns->bdev != NULL); 250a35b1eb6SDaniel Verkamp num_blocks = ns->bdev->blockcnt; 251a35b1eb6SDaniel Verkamp nsdata->nsze = num_blocks; 252a35b1eb6SDaniel Verkamp nsdata->ncap = num_blocks; 253a35b1eb6SDaniel Verkamp nsdata->nuse = num_blocks; 254a35b1eb6SDaniel Verkamp nsdata->nlbaf = 0; 255a35b1eb6SDaniel Verkamp nsdata->flbas.format = 0; 2567bbeb80aSAnkit Kumar nsdata->flbas.msb_format = 0; 257a35b1eb6SDaniel Verkamp nsdata->lbaf[0].lbads = spdk_u32log2(512); 258a35b1eb6SDaniel Verkamp } 259a35b1eb6SDaniel Verkamp 2605e4d957eSShuhei Matsumoto void 2615e4d957eSShuhei Matsumoto nvmf_bdev_ctrlr_identify_iocs_nvm(struct spdk_nvmf_ns *ns, 2625e4d957eSShuhei Matsumoto struct spdk_nvme_nvm_ns_data *nsdata_nvm) 2635e4d957eSShuhei Matsumoto { 2645e4d957eSShuhei Matsumoto if (ns->bdev->dif_type == SPDK_DIF_DISABLE) { 2655e4d957eSShuhei Matsumoto return; 2665e4d957eSShuhei Matsumoto } 2675e4d957eSShuhei Matsumoto 2685e4d957eSShuhei Matsumoto nsdata_nvm->lbstm = 0; 2695e4d957eSShuhei Matsumoto nsdata_nvm->pic._16bpists = 0; 2705e4d957eSShuhei Matsumoto nsdata_nvm->pic._16bpistm = 1; 2715e4d957eSShuhei Matsumoto nsdata_nvm->pic.stcrs = 0; 2725e4d957eSShuhei Matsumoto nsdata_nvm->elbaf[0].sts = 16; 2735e4d957eSShuhei Matsumoto nsdata_nvm->elbaf[0].pif = SPDK_DIF_PI_FORMAT_32; 2745e4d957eSShuhei Matsumoto } 2755e4d957eSShuhei Matsumoto 27674f8f371SMonica Kenguva struct spdk_nvmf_ns * 27774f8f371SMonica Kenguva spdk_nvmf_subsystem_get_first_ns(struct spdk_nvmf_subsystem *subsystem) 27874f8f371SMonica Kenguva { 27974f8f371SMonica Kenguva SPDK_CU_ASSERT_FATAL(subsystem->ns != NULL); 28074f8f371SMonica Kenguva return subsystem->ns[0]; 28174f8f371SMonica Kenguva } 28274f8f371SMonica Kenguva 28374f8f371SMonica Kenguva struct spdk_nvmf_ns * 28474f8f371SMonica Kenguva spdk_nvmf_subsystem_get_next_ns(struct spdk_nvmf_subsystem *subsystem, 28574f8f371SMonica Kenguva struct spdk_nvmf_ns *prev_ns) 28674f8f371SMonica Kenguva { 28774f8f371SMonica Kenguva uint32_t nsid; 28874f8f371SMonica Kenguva 28974f8f371SMonica Kenguva SPDK_CU_ASSERT_FATAL(subsystem->ns != NULL); 29074f8f371SMonica Kenguva nsid = prev_ns->nsid; 29174f8f371SMonica Kenguva 29274f8f371SMonica Kenguva if (nsid >= subsystem->max_nsid) { 29374f8f371SMonica Kenguva return NULL; 29474f8f371SMonica Kenguva } 29574f8f371SMonica Kenguva for (nsid = nsid + 1; nsid <= subsystem->max_nsid; nsid++) { 29674f8f371SMonica Kenguva if (subsystem->ns[nsid - 1]) { 29774f8f371SMonica Kenguva return subsystem->ns[nsid - 1]; 29874f8f371SMonica Kenguva } 29974f8f371SMonica Kenguva } 30074f8f371SMonica Kenguva return NULL; 30174f8f371SMonica Kenguva } 30274f8f371SMonica Kenguva 3035818b42fSmatthewb bool 3045818b42fSmatthewb nvmf_bdev_zcopy_enabled(struct spdk_bdev *bdev) 3055818b42fSmatthewb { 3065818b42fSmatthewb return true; 3075818b42fSmatthewb } 3085818b42fSmatthewb 3095818b42fSmatthewb int 3100e09df57SKonrad Sztyber nvmf_bdev_ctrlr_zcopy_start(struct spdk_bdev *bdev, 3115818b42fSmatthewb struct spdk_bdev_desc *desc, 3125818b42fSmatthewb struct spdk_io_channel *ch, 3135818b42fSmatthewb struct spdk_nvmf_request *req) 3145818b42fSmatthewb { 31592d7df1fSKonrad Sztyber struct spdk_nvme_cpl *rsp = &req->rsp->nvme_cpl; 3165818b42fSmatthewb uint64_t start_lba; 3175818b42fSmatthewb uint64_t num_blocks; 3185818b42fSmatthewb 3195818b42fSmatthewb start_lba = from_le64(&req->cmd->nvme_cmd.cdw10); 3205818b42fSmatthewb num_blocks = (from_le32(&req->cmd->nvme_cmd.cdw12) & 0xFFFFu) + 1; 3215818b42fSmatthewb 3225818b42fSmatthewb if ((start_lba + num_blocks) > bdev->blockcnt) { 32392d7df1fSKonrad Sztyber rsp->status.sct = SPDK_NVME_SCT_GENERIC; 32492d7df1fSKonrad Sztyber rsp->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID; 32592d7df1fSKonrad Sztyber return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 3265818b42fSmatthewb } 3275818b42fSmatthewb 3285818b42fSmatthewb if (req->cmd->nvme_cmd.opc == SPDK_NVME_OPC_WRITE) { 3295818b42fSmatthewb req->zcopy_bdev_io = zcopy_start_bdev_io_write; 3305818b42fSmatthewb } else if (req->cmd->nvme_cmd.opc == SPDK_NVME_OPC_READ) { 3315818b42fSmatthewb req->zcopy_bdev_io = zcopy_start_bdev_io_read; 3325818b42fSmatthewb } else { 3335818b42fSmatthewb req->zcopy_bdev_io = zcopy_start_bdev_io_fail; 3345818b42fSmatthewb } 3355818b42fSmatthewb 3365818b42fSmatthewb 33792d7df1fSKonrad Sztyber return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 3385818b42fSmatthewb } 3395818b42fSmatthewb 3407a374fbcSKonrad Sztyber void 3410e09df57SKonrad Sztyber nvmf_bdev_ctrlr_zcopy_end(struct spdk_nvmf_request *req, bool commit) 3425818b42fSmatthewb { 3435818b42fSmatthewb req->zcopy_bdev_io = NULL; 3445818b42fSmatthewb spdk_nvmf_request_complete(req); 3455818b42fSmatthewb } 3465818b42fSmatthewb 34709e8e884SArtur Paszkiewicz bool 34809e8e884SArtur Paszkiewicz nvmf_ns_is_ptpl_capable(const struct spdk_nvmf_ns *ns) 34909e8e884SArtur Paszkiewicz { 35009e8e884SArtur Paszkiewicz return ns->ptpl_file != NULL; 35109e8e884SArtur Paszkiewicz } 35209e8e884SArtur Paszkiewicz 35389d35cefSDaniel Verkamp static void 35489d35cefSDaniel Verkamp test_get_log_page(void) 35589d35cefSDaniel Verkamp { 35689d35cefSDaniel Verkamp struct spdk_nvmf_subsystem subsystem = {}; 35789d35cefSDaniel Verkamp struct spdk_nvmf_request req = {}; 35889d35cefSDaniel Verkamp struct spdk_nvmf_qpair qpair = {}; 35989d35cefSDaniel Verkamp struct spdk_nvmf_ctrlr ctrlr = {}; 36089d35cefSDaniel Verkamp union nvmf_h2c_msg cmd = {}; 36189d35cefSDaniel Verkamp union nvmf_c2h_msg rsp = {}; 36289d35cefSDaniel Verkamp char data[4096]; 36389d35cefSDaniel Verkamp 36489d35cefSDaniel Verkamp subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 36589d35cefSDaniel Verkamp 36689d35cefSDaniel Verkamp ctrlr.subsys = &subsystem; 36789d35cefSDaniel Verkamp 36889d35cefSDaniel Verkamp qpair.ctrlr = &ctrlr; 36989d35cefSDaniel Verkamp 37089d35cefSDaniel Verkamp req.qpair = &qpair; 37189d35cefSDaniel Verkamp req.cmd = &cmd; 37289d35cefSDaniel Verkamp req.rsp = &rsp; 37389d35cefSDaniel Verkamp req.length = sizeof(data); 374f029b824SJacek Kalwas SPDK_IOV_ONE(req.iov, &req.iovcnt, &data, req.length); 37589d35cefSDaniel Verkamp 37689d35cefSDaniel Verkamp /* Get Log Page - all valid */ 37789d35cefSDaniel Verkamp memset(&cmd, 0, sizeof(cmd)); 37889d35cefSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 37989d35cefSDaniel Verkamp cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE; 3801fea1fccSChangpeng Liu cmd.nvme_cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_ERROR; 3811572882aSsunshihao520 cmd.nvme_cmd.cdw10_bits.get_log_page.numdl = spdk_nvme_bytes_to_numd(req.length); 382198fd2ceSSeth Howell CU_ASSERT(nvmf_ctrlr_get_log_page(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 38389d35cefSDaniel Verkamp CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 38489d35cefSDaniel Verkamp CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 38589d35cefSDaniel Verkamp 38689d35cefSDaniel Verkamp /* Get Log Page with invalid log ID */ 38789d35cefSDaniel Verkamp memset(&cmd, 0, sizeof(cmd)); 38889d35cefSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 38989d35cefSDaniel Verkamp cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE; 39089d35cefSDaniel Verkamp cmd.nvme_cmd.cdw10 = 0; 391198fd2ceSSeth Howell CU_ASSERT(nvmf_ctrlr_get_log_page(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 39289d35cefSDaniel Verkamp CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 39389d35cefSDaniel Verkamp CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 39489d35cefSDaniel Verkamp 39589d35cefSDaniel Verkamp /* Get Log Page with invalid offset (not dword aligned) */ 39689d35cefSDaniel Verkamp memset(&cmd, 0, sizeof(cmd)); 39789d35cefSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 39889d35cefSDaniel Verkamp cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE; 3991fea1fccSChangpeng Liu cmd.nvme_cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_ERROR; 4001572882aSsunshihao520 cmd.nvme_cmd.cdw10_bits.get_log_page.numdl = spdk_nvme_bytes_to_numd(req.length); 40189d35cefSDaniel Verkamp cmd.nvme_cmd.cdw12 = 2; 402198fd2ceSSeth Howell CU_ASSERT(nvmf_ctrlr_get_log_page(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 40389d35cefSDaniel Verkamp CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 40489d35cefSDaniel Verkamp CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 40589d35cefSDaniel Verkamp 40689d35cefSDaniel Verkamp /* Get Log Page without data buffer */ 40789d35cefSDaniel Verkamp memset(&cmd, 0, sizeof(cmd)); 40889d35cefSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 4099fa25237SJohn Levon req.iovcnt = 0; 41089d35cefSDaniel Verkamp cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE; 4111fea1fccSChangpeng Liu cmd.nvme_cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_ERROR; 4121572882aSsunshihao520 cmd.nvme_cmd.cdw10_bits.get_log_page.numdl = spdk_nvme_bytes_to_numd(req.length); 413198fd2ceSSeth Howell CU_ASSERT(nvmf_ctrlr_get_log_page(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 41489d35cefSDaniel Verkamp CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 41589d35cefSDaniel Verkamp CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 41689d35cefSDaniel Verkamp } 41789d35cefSDaniel Verkamp 4185323a026SDaniel Verkamp static void 4195323a026SDaniel Verkamp test_process_fabrics_cmd(void) 4205323a026SDaniel Verkamp { 4215323a026SDaniel Verkamp struct spdk_nvmf_request req = {}; 42233e23361SKonrad Sztyber bool ret; 4235323a026SDaniel Verkamp struct spdk_nvmf_qpair req_qpair = {}; 4245323a026SDaniel Verkamp union nvmf_h2c_msg req_cmd = {}; 4255323a026SDaniel Verkamp union nvmf_c2h_msg req_rsp = {}; 4265323a026SDaniel Verkamp 42733e23361SKonrad Sztyber TAILQ_INIT(&req_qpair.outstanding); 42833e23361SKonrad Sztyber req_qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 4295323a026SDaniel Verkamp req.qpair = &req_qpair; 4305323a026SDaniel Verkamp req.cmd = &req_cmd; 4315323a026SDaniel Verkamp req.rsp = &req_rsp; 4325323a026SDaniel Verkamp req.qpair->ctrlr = NULL; 4335323a026SDaniel Verkamp 4345323a026SDaniel Verkamp /* No ctrlr and invalid command check */ 4355323a026SDaniel Verkamp req.cmd->nvmf_cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_PROPERTY_GET; 43633e23361SKonrad Sztyber ret = nvmf_check_qpair_active(&req); 43733e23361SKonrad Sztyber CU_ASSERT_EQUAL(req.rsp->nvme_cpl.status.sct, SPDK_NVME_SCT_GENERIC); 4385323a026SDaniel Verkamp CU_ASSERT_EQUAL(req.rsp->nvme_cpl.status.sc, SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR); 43933e23361SKonrad Sztyber CU_ASSERT(ret == false); 4405323a026SDaniel Verkamp } 4415323a026SDaniel Verkamp 442fab9349fSDaniel Verkamp static bool 443fab9349fSDaniel Verkamp nvme_status_success(const struct spdk_nvme_status *status) 444fab9349fSDaniel Verkamp { 445fab9349fSDaniel Verkamp return status->sct == SPDK_NVME_SCT_GENERIC && status->sc == SPDK_NVME_SC_SUCCESS; 446fab9349fSDaniel Verkamp } 447fab9349fSDaniel Verkamp 448fab9349fSDaniel Verkamp static void 449fab9349fSDaniel Verkamp test_connect(void) 450fab9349fSDaniel Verkamp { 451fab9349fSDaniel Verkamp struct spdk_nvmf_fabric_connect_data connect_data; 452fab9349fSDaniel Verkamp struct spdk_nvmf_poll_group group; 4538fc9ac7bSJinYu struct spdk_nvmf_subsystem_poll_group *sgroups; 454fab9349fSDaniel Verkamp struct spdk_nvmf_transport transport; 455000e6f5bSJacek Kalwas struct spdk_nvmf_transport_ops tops = {}; 456fab9349fSDaniel Verkamp struct spdk_nvmf_subsystem subsystem; 457d37555b4SJonas Pfefferle struct spdk_nvmf_ns *ns_arr[1] = { NULL }; 458fab9349fSDaniel Verkamp struct spdk_nvmf_request req; 45930ef8cacSZiye Yang struct spdk_nvmf_qpair admin_qpair; 460fab9349fSDaniel Verkamp struct spdk_nvmf_qpair qpair; 461fab9349fSDaniel Verkamp struct spdk_nvmf_ctrlr ctrlr; 462fab9349fSDaniel Verkamp struct spdk_nvmf_tgt tgt; 463fab9349fSDaniel Verkamp union nvmf_h2c_msg cmd; 464fab9349fSDaniel Verkamp union nvmf_c2h_msg rsp; 465fab9349fSDaniel Verkamp const uint8_t hostid[16] = { 466fab9349fSDaniel Verkamp 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 467fab9349fSDaniel Verkamp 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F 468fab9349fSDaniel Verkamp }; 469fab9349fSDaniel Verkamp const char subnqn[] = "nqn.2016-06.io.spdk:subsystem1"; 470fab9349fSDaniel Verkamp const char hostnqn[] = "nqn.2016-06.io.spdk:host1"; 471fab9349fSDaniel Verkamp int rc; 472fab9349fSDaniel Verkamp 473fab9349fSDaniel Verkamp memset(&group, 0, sizeof(group)); 474f6f1161fSBen Walker group.thread = spdk_get_thread(); 475fab9349fSDaniel Verkamp 476fab9349fSDaniel Verkamp memset(&ctrlr, 0, sizeof(ctrlr)); 477fab9349fSDaniel Verkamp ctrlr.subsys = &subsystem; 478f08cea71SBen Walker ctrlr.qpair_mask = spdk_bit_array_create(3); 479f08cea71SBen Walker SPDK_CU_ASSERT_FATAL(ctrlr.qpair_mask != NULL); 480fab9349fSDaniel Verkamp ctrlr.vcprop.cc.bits.en = 1; 481fab9349fSDaniel Verkamp ctrlr.vcprop.cc.bits.iosqes = 6; 482fab9349fSDaniel Verkamp ctrlr.vcprop.cc.bits.iocqes = 4; 483fab9349fSDaniel Verkamp 48430ef8cacSZiye Yang memset(&admin_qpair, 0, sizeof(admin_qpair)); 48530ef8cacSZiye Yang admin_qpair.group = &group; 486db221b40SKonrad Sztyber admin_qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 48730ef8cacSZiye Yang 488fab9349fSDaniel Verkamp memset(&tgt, 0, sizeof(tgt)); 489fab9349fSDaniel Verkamp memset(&transport, 0, sizeof(transport)); 490000e6f5bSJacek Kalwas transport.ops = &tops; 49120618744SAnil Veerabhadrappa transport.opts.max_aq_depth = 32; 4928e808490SJohn Barnard transport.opts.max_queue_depth = 64; 4938e808490SJohn Barnard transport.opts.max_qpairs_per_ctrlr = 3; 494fab9349fSDaniel Verkamp transport.tgt = &tgt; 495fab9349fSDaniel Verkamp 496fab9349fSDaniel Verkamp memset(&qpair, 0, sizeof(qpair)); 497fab9349fSDaniel Verkamp qpair.transport = &transport; 49830ef8cacSZiye Yang qpair.group = &group; 499db221b40SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 500a4d666fdSBen Walker TAILQ_INIT(&qpair.outstanding); 501fab9349fSDaniel Verkamp 502fab9349fSDaniel Verkamp memset(&connect_data, 0, sizeof(connect_data)); 503fab9349fSDaniel Verkamp memcpy(connect_data.hostid, hostid, sizeof(hostid)); 504fab9349fSDaniel Verkamp connect_data.cntlid = 0xFFFF; 505931b7d1fSBen Walker snprintf(connect_data.subnqn, sizeof(connect_data.subnqn), "%s", subnqn); 506931b7d1fSBen Walker snprintf(connect_data.hostnqn, sizeof(connect_data.hostnqn), "%s", hostnqn); 507fab9349fSDaniel Verkamp 508fab9349fSDaniel Verkamp memset(&subsystem, 0, sizeof(subsystem)); 509f6f1161fSBen Walker subsystem.thread = spdk_get_thread(); 510fab9349fSDaniel Verkamp subsystem.id = 1; 511fab9349fSDaniel Verkamp TAILQ_INIT(&subsystem.ctrlrs); 512fab9349fSDaniel Verkamp subsystem.tgt = &tgt; 513fab9349fSDaniel Verkamp subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 514f3109678SZiye Yang subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 515fab9349fSDaniel Verkamp snprintf(subsystem.subnqn, sizeof(subsystem.subnqn), "%s", subnqn); 516d37555b4SJonas Pfefferle subsystem.ns = ns_arr; 517d37555b4SJonas Pfefferle subsystem.max_nsid = 1; 518fab9349fSDaniel Verkamp 5198fc9ac7bSJinYu sgroups = calloc(subsystem.id + 1, sizeof(struct spdk_nvmf_subsystem_poll_group)); 5208fc9ac7bSJinYu group.sgroups = sgroups; 5218fc9ac7bSJinYu 522fab9349fSDaniel Verkamp memset(&cmd, 0, sizeof(cmd)); 523fab9349fSDaniel Verkamp cmd.connect_cmd.opcode = SPDK_NVME_OPC_FABRIC; 524fab9349fSDaniel Verkamp cmd.connect_cmd.cid = 1; 525fab9349fSDaniel Verkamp cmd.connect_cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_CONNECT; 526fab9349fSDaniel Verkamp cmd.connect_cmd.recfmt = 0; 527fab9349fSDaniel Verkamp cmd.connect_cmd.qid = 0; 528fab9349fSDaniel Verkamp cmd.connect_cmd.sqsize = 31; 529fab9349fSDaniel Verkamp cmd.connect_cmd.cattr = 0; 530fab9349fSDaniel Verkamp cmd.connect_cmd.kato = 120000; 531fab9349fSDaniel Verkamp 532fab9349fSDaniel Verkamp memset(&req, 0, sizeof(req)); 533fab9349fSDaniel Verkamp req.qpair = &qpair; 534fab9349fSDaniel Verkamp req.xfer = SPDK_NVME_DATA_HOST_TO_CONTROLLER; 5359fa25237SJohn Levon req.length = sizeof(connect_data); 536f029b824SJacek Kalwas SPDK_IOV_ONE(req.iov, &req.iovcnt, &connect_data, req.length); 537fab9349fSDaniel Verkamp req.cmd = &cmd; 538fab9349fSDaniel Verkamp req.rsp = &rsp; 539fab9349fSDaniel Verkamp 540f56b2300SBen Walker MOCK_SET(spdk_nvmf_tgt_find_subsystem, &subsystem); 541f56b2300SBen Walker MOCK_SET(spdk_nvmf_poll_group_create, &group); 542fab9349fSDaniel Verkamp 543fab9349fSDaniel Verkamp /* Valid admin connect command */ 544fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 545312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 546a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 547*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 548198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 54906a0d9abSBen Walker poll_threads(); 5507346be69SZiye Yang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 551fab9349fSDaniel Verkamp CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 552fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr != NULL); 553db221b40SKonrad Sztyber CU_ASSERT(qpair.state == SPDK_NVMF_QPAIR_ENABLED); 554312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 555198fd2ceSSeth Howell nvmf_ctrlr_stop_keep_alive_timer(qpair.ctrlr); 556f08cea71SBen Walker spdk_bit_array_free(&qpair.ctrlr->qpair_mask); 557d37555b4SJonas Pfefferle free(qpair.ctrlr->visible_ns); 558fab9349fSDaniel Verkamp free(qpair.ctrlr); 559db221b40SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 560fab9349fSDaniel Verkamp qpair.ctrlr = NULL; 561fab9349fSDaniel Verkamp 56250a130c6SJinYu /* Valid admin connect command with kato = 0 */ 56350a130c6SJinYu cmd.connect_cmd.kato = 0; 56450a130c6SJinYu memset(&rsp, 0, sizeof(rsp)); 565312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 56650a130c6SJinYu TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 567*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 568198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 56950a130c6SJinYu poll_threads(); 57050a130c6SJinYu CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 57150a130c6SJinYu CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 57250a130c6SJinYu CU_ASSERT(qpair.ctrlr != NULL && qpair.ctrlr->keep_alive_poller == NULL); 573db221b40SKonrad Sztyber CU_ASSERT(qpair.state == SPDK_NVMF_QPAIR_ENABLED); 574312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 57550a130c6SJinYu spdk_bit_array_free(&qpair.ctrlr->qpair_mask); 576d37555b4SJonas Pfefferle free(qpair.ctrlr->visible_ns); 57750a130c6SJinYu free(qpair.ctrlr); 578db221b40SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 57950a130c6SJinYu qpair.ctrlr = NULL; 58050a130c6SJinYu cmd.connect_cmd.kato = 120000; 58150a130c6SJinYu 582fab9349fSDaniel Verkamp /* Invalid data length */ 583fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 584fab9349fSDaniel Verkamp req.length = sizeof(connect_data) - 1; 585a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 586*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 587198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 58806a0d9abSBen Walker poll_threads(); 589fab9349fSDaniel Verkamp CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 590fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 591fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 592fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 593fab9349fSDaniel Verkamp req.length = sizeof(connect_data); 594fab9349fSDaniel Verkamp 595fab9349fSDaniel Verkamp /* Invalid recfmt */ 596fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 597fab9349fSDaniel Verkamp cmd.connect_cmd.recfmt = 1234; 598a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 599*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 600198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 60106a0d9abSBen Walker poll_threads(); 602fab9349fSDaniel Verkamp CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 603fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 604fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INCOMPATIBLE_FORMAT); 605fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 606fab9349fSDaniel Verkamp cmd.connect_cmd.recfmt = 0; 607fab9349fSDaniel Verkamp 608fab9349fSDaniel Verkamp /* Subsystem not found */ 609fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 610f56b2300SBen Walker MOCK_SET(spdk_nvmf_tgt_find_subsystem, NULL); 611a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 612*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 613198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 61406a0d9abSBen Walker poll_threads(); 615fab9349fSDaniel Verkamp CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 616fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 617fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 618fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 1); 619fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 256); 620fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 621f56b2300SBen Walker MOCK_SET(spdk_nvmf_tgt_find_subsystem, &subsystem); 622fab9349fSDaniel Verkamp 623fab9349fSDaniel Verkamp /* Unterminated hostnqn */ 624fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 625fab9349fSDaniel Verkamp memset(connect_data.hostnqn, 'b', sizeof(connect_data.hostnqn)); 626a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 627*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 628198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 62906a0d9abSBen Walker poll_threads(); 630fab9349fSDaniel Verkamp CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 631fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 632fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 633fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 1); 634fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 512); 635fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 636931b7d1fSBen Walker snprintf(connect_data.hostnqn, sizeof(connect_data.hostnqn), "%s", hostnqn); 637fab9349fSDaniel Verkamp 638fab9349fSDaniel Verkamp /* Host not allowed */ 639fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 640f56b2300SBen Walker MOCK_SET(spdk_nvmf_subsystem_host_allowed, false); 641a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 642*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 643198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 64406a0d9abSBen Walker poll_threads(); 645fab9349fSDaniel Verkamp CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 646fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 647fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_HOST); 648fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 649f56b2300SBen Walker MOCK_SET(spdk_nvmf_subsystem_host_allowed, true); 650fab9349fSDaniel Verkamp 651fab9349fSDaniel Verkamp /* Invalid sqsize == 0 */ 652fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 653fab9349fSDaniel Verkamp cmd.connect_cmd.sqsize = 0; 654a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 655*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 656198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 65706a0d9abSBen Walker poll_threads(); 658fab9349fSDaniel Verkamp CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 659fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 660fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 661fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 662fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 44); 663fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 664fab9349fSDaniel Verkamp cmd.connect_cmd.sqsize = 31; 665fab9349fSDaniel Verkamp 6669e3d841dSEvgeniy Kochetov /* Invalid admin sqsize > max_aq_depth */ 667fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 6689e3d841dSEvgeniy Kochetov cmd.connect_cmd.sqsize = 32; 6699e3d841dSEvgeniy Kochetov TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 670*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 671198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 6729e3d841dSEvgeniy Kochetov poll_threads(); 6739e3d841dSEvgeniy Kochetov CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 6749e3d841dSEvgeniy Kochetov CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 6759e3d841dSEvgeniy Kochetov CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 6769e3d841dSEvgeniy Kochetov CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 6779e3d841dSEvgeniy Kochetov CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 44); 6789e3d841dSEvgeniy Kochetov CU_ASSERT(qpair.ctrlr == NULL); 6799e3d841dSEvgeniy Kochetov cmd.connect_cmd.sqsize = 31; 6809e3d841dSEvgeniy Kochetov 6819e3d841dSEvgeniy Kochetov /* Invalid I/O sqsize > max_queue_depth */ 6829e3d841dSEvgeniy Kochetov memset(&rsp, 0, sizeof(rsp)); 6839e3d841dSEvgeniy Kochetov cmd.connect_cmd.qid = 1; 684fab9349fSDaniel Verkamp cmd.connect_cmd.sqsize = 64; 685a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 686*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 687198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 68806a0d9abSBen Walker poll_threads(); 689fab9349fSDaniel Verkamp CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 690fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 691fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 692fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 693fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 44); 694fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 6959e3d841dSEvgeniy Kochetov cmd.connect_cmd.qid = 0; 696fab9349fSDaniel Verkamp cmd.connect_cmd.sqsize = 31; 697fab9349fSDaniel Verkamp 698fab9349fSDaniel Verkamp /* Invalid cntlid for admin queue */ 699fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 700fab9349fSDaniel Verkamp connect_data.cntlid = 0x1234; 701a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 702*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 703198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 70406a0d9abSBen Walker poll_threads(); 705fab9349fSDaniel Verkamp CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 706fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 707fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 708fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 1); 709fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 16); 710fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 711fab9349fSDaniel Verkamp connect_data.cntlid = 0xFFFF; 712fab9349fSDaniel Verkamp 71330ef8cacSZiye Yang ctrlr.admin_qpair = &admin_qpair; 71430ef8cacSZiye Yang ctrlr.subsys = &subsystem; 71530ef8cacSZiye Yang 716fab9349fSDaniel Verkamp /* Valid I/O queue connect command */ 717fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 7189cb21ad6SSeth Howell MOCK_SET(nvmf_subsystem_get_ctrlr, &ctrlr); 719fab9349fSDaniel Verkamp cmd.connect_cmd.qid = 1; 7209e3d841dSEvgeniy Kochetov cmd.connect_cmd.sqsize = 63; 721312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 722a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 723*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 724198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 72506a0d9abSBen Walker poll_threads(); 72630ef8cacSZiye Yang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 727fab9349fSDaniel Verkamp CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 728db221b40SKonrad Sztyber CU_ASSERT(qpair.state == SPDK_NVMF_QPAIR_ENABLED); 729fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == &ctrlr); 730312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 731fab9349fSDaniel Verkamp qpair.ctrlr = NULL; 732db221b40SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 7339e3d841dSEvgeniy Kochetov cmd.connect_cmd.sqsize = 31; 734fab9349fSDaniel Verkamp 735fab9349fSDaniel Verkamp /* Non-existent controller */ 736fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 7379cb21ad6SSeth Howell MOCK_SET(nvmf_subsystem_get_ctrlr, NULL); 738312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 739a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 740*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 741198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 74206a0d9abSBen Walker poll_threads(); 7437346be69SZiye Yang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 744fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 745fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 746fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 1); 747fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 16); 748fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 749312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 7509cb21ad6SSeth Howell MOCK_SET(nvmf_subsystem_get_ctrlr, &ctrlr); 751fab9349fSDaniel Verkamp 752fab9349fSDaniel Verkamp /* I/O connect to discovery controller */ 753fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 7547efdf905SSlawomir Ptak subsystem.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY_CURRENT; 7557efdf905SSlawomir Ptak MOCK_SET(spdk_nvmf_subsystem_is_discovery, true); 756f3109678SZiye Yang subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 757312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 758a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 759*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 760198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 76106a0d9abSBen Walker poll_threads(); 76230ef8cacSZiye Yang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 763fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 764fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 765fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 766fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 42); 767fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 768312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 76950a130c6SJinYu 770e37fc5a3SShuhei Matsumoto /* I/O connect to discovery controller with keep-alive-timeout != 0 */ 77150a130c6SJinYu cmd.connect_cmd.qid = 0; 772e37fc5a3SShuhei Matsumoto cmd.connect_cmd.kato = 120000; 77350a130c6SJinYu memset(&rsp, 0, sizeof(rsp)); 7747efdf905SSlawomir Ptak subsystem.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY_CURRENT; 7757efdf905SSlawomir Ptak MOCK_SET(spdk_nvmf_subsystem_is_discovery, true); 77650a130c6SJinYu subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 777312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 77850a130c6SJinYu TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 779*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 780198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 78150a130c6SJinYu poll_threads(); 782e37fc5a3SShuhei Matsumoto CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 783e37fc5a3SShuhei Matsumoto CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 784db221b40SKonrad Sztyber CU_ASSERT(qpair.state == SPDK_NVMF_QPAIR_ENABLED); 785e37fc5a3SShuhei Matsumoto CU_ASSERT(qpair.ctrlr != NULL); 786e37fc5a3SShuhei Matsumoto CU_ASSERT(qpair.ctrlr->keep_alive_poller != NULL); 787312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 788198fd2ceSSeth Howell nvmf_ctrlr_stop_keep_alive_timer(qpair.ctrlr); 789e37fc5a3SShuhei Matsumoto spdk_bit_array_free(&qpair.ctrlr->qpair_mask); 790d37555b4SJonas Pfefferle free(qpair.ctrlr->visible_ns); 791e37fc5a3SShuhei Matsumoto free(qpair.ctrlr); 792db221b40SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 793e37fc5a3SShuhei Matsumoto qpair.ctrlr = NULL; 794e37fc5a3SShuhei Matsumoto 795e37fc5a3SShuhei Matsumoto /* I/O connect to discovery controller with keep-alive-timeout == 0. 796e37fc5a3SShuhei Matsumoto * Then, a fixed timeout value is set to keep-alive-timeout. 797e37fc5a3SShuhei Matsumoto */ 798e37fc5a3SShuhei Matsumoto cmd.connect_cmd.kato = 0; 799e37fc5a3SShuhei Matsumoto memset(&rsp, 0, sizeof(rsp)); 8007efdf905SSlawomir Ptak subsystem.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY_CURRENT; 8017efdf905SSlawomir Ptak MOCK_SET(spdk_nvmf_subsystem_is_discovery, true); 802e37fc5a3SShuhei Matsumoto subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 803312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 804e37fc5a3SShuhei Matsumoto TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 805*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 806198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 807e37fc5a3SShuhei Matsumoto poll_threads(); 808e37fc5a3SShuhei Matsumoto CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 809e37fc5a3SShuhei Matsumoto CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 810db221b40SKonrad Sztyber CU_ASSERT(qpair.state == SPDK_NVMF_QPAIR_ENABLED); 811e37fc5a3SShuhei Matsumoto CU_ASSERT(qpair.ctrlr != NULL); 812e37fc5a3SShuhei Matsumoto CU_ASSERT(qpair.ctrlr->keep_alive_poller != NULL); 813312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 814198fd2ceSSeth Howell nvmf_ctrlr_stop_keep_alive_timer(qpair.ctrlr); 815e37fc5a3SShuhei Matsumoto spdk_bit_array_free(&qpair.ctrlr->qpair_mask); 816d37555b4SJonas Pfefferle free(qpair.ctrlr->visible_ns); 817e37fc5a3SShuhei Matsumoto free(qpair.ctrlr); 818db221b40SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 819e37fc5a3SShuhei Matsumoto qpair.ctrlr = NULL; 82050a130c6SJinYu cmd.connect_cmd.qid = 1; 821e37fc5a3SShuhei Matsumoto cmd.connect_cmd.kato = 120000; 822fab9349fSDaniel Verkamp subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 8237efdf905SSlawomir Ptak MOCK_SET(spdk_nvmf_subsystem_is_discovery, false); 824fab9349fSDaniel Verkamp 825fab9349fSDaniel Verkamp /* I/O connect to disabled controller */ 826fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 827fab9349fSDaniel Verkamp ctrlr.vcprop.cc.bits.en = 0; 828312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 829a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 830*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 831198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 83206a0d9abSBen Walker poll_threads(); 83330ef8cacSZiye Yang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 834fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 835fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 836fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 837fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 42); 838fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 839312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 840fab9349fSDaniel Verkamp ctrlr.vcprop.cc.bits.en = 1; 841fab9349fSDaniel Verkamp 842fab9349fSDaniel Verkamp /* I/O connect with invalid IOSQES */ 843fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 844fab9349fSDaniel Verkamp ctrlr.vcprop.cc.bits.iosqes = 3; 845312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 846a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 847*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 848198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 84906a0d9abSBen Walker poll_threads(); 85030ef8cacSZiye Yang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 851fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 852fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 853fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 854fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 42); 855fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 856312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 857fab9349fSDaniel Verkamp ctrlr.vcprop.cc.bits.iosqes = 6; 858fab9349fSDaniel Verkamp 859fab9349fSDaniel Verkamp /* I/O connect with invalid IOCQES */ 860fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 861fab9349fSDaniel Verkamp ctrlr.vcprop.cc.bits.iocqes = 3; 862312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 863a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 864*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 865198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 86606a0d9abSBen Walker poll_threads(); 86730ef8cacSZiye Yang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 868fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 869fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 870fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 0); 871fab9349fSDaniel Verkamp CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 42); 872fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 873312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 874fab9349fSDaniel Verkamp ctrlr.vcprop.cc.bits.iocqes = 4; 875fab9349fSDaniel Verkamp 876736e1c1bSJim Harris /* I/O connect with qid that is too large */ 877fab9349fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 878736e1c1bSJim Harris cmd.connect_cmd.qid = 3; 879312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 880a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 881*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 882198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 88306a0d9abSBen Walker poll_threads(); 88430ef8cacSZiye Yang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 885fab9349fSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 886b95fc6fcSBen Walker CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER); 887fab9349fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 888312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 889fab9349fSDaniel Verkamp 890bedc405fSDaniel Verkamp /* I/O connect with duplicate queue ID */ 891bedc405fSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 892f08cea71SBen Walker spdk_bit_array_set(ctrlr.qpair_mask, 1); 893bedc405fSDaniel Verkamp cmd.connect_cmd.qid = 1; 894312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 895a4d666fdSBen Walker TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 896*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 897198fd2ceSSeth Howell rc = nvmf_ctrlr_cmd_connect(&req); 89830ef8cacSZiye Yang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 899b1a23196SJim Harris poll_threads(); 900b1a23196SJim Harris /* First time, it will detect duplicate QID and schedule a retry. So for 901b1a23196SJim Harris * now we should expect the response to still be all zeroes. 902b1a23196SJim Harris */ 903b1a23196SJim Harris CU_ASSERT(spdk_mem_all_zero(&rsp, sizeof(rsp))); 904b1a23196SJim Harris CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 1); 905b1a23196SJim Harris 906b1a23196SJim Harris /* Now advance the clock, so that the retry poller executes. */ 907b1a23196SJim Harris spdk_delay_us(DUPLICATE_QID_RETRY_US * 2); 908b1a23196SJim Harris poll_threads(); 909b95fc6fcSBen Walker CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 910b95fc6fcSBen Walker CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER); 911bedc405fSDaniel Verkamp CU_ASSERT(qpair.ctrlr == NULL); 912312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 913bedc405fSDaniel Verkamp 914b1a23196SJim Harris /* I/O connect with temporarily duplicate queue ID. This covers race 915b1a23196SJim Harris * where qpair_mask bit may not yet be cleared, even though initiator 916b1a23196SJim Harris * has closed the connection. See issue #2955. */ 917b1a23196SJim Harris memset(&rsp, 0, sizeof(rsp)); 918b1a23196SJim Harris sgroups[subsystem.id].mgmt_io_outstanding++; 919b1a23196SJim Harris TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 920*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 921b1a23196SJim Harris rc = nvmf_ctrlr_cmd_connect(&req); 922b1a23196SJim Harris CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 923b1a23196SJim Harris poll_threads(); 924b1a23196SJim Harris /* First time, it will detect duplicate QID and schedule a retry. So for 925b1a23196SJim Harris * now we should expect the response to still be all zeroes. 926b1a23196SJim Harris */ 927b1a23196SJim Harris CU_ASSERT(spdk_mem_all_zero(&rsp, sizeof(rsp))); 928b1a23196SJim Harris CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 1); 929b1a23196SJim Harris 930b1a23196SJim Harris /* Now advance the clock, so that the retry poller executes. */ 931b1a23196SJim Harris spdk_bit_array_clear(ctrlr.qpair_mask, 1); 932b1a23196SJim Harris spdk_delay_us(DUPLICATE_QID_RETRY_US * 2); 933b1a23196SJim Harris poll_threads(); 934b1a23196SJim Harris CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 935db221b40SKonrad Sztyber CU_ASSERT(qpair.state == SPDK_NVMF_QPAIR_ENABLED); 936b1a23196SJim Harris CU_ASSERT(qpair.ctrlr == &ctrlr); 937b1a23196SJim Harris CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 938db221b40SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 939b1a23196SJim Harris qpair.ctrlr = NULL; 940b1a23196SJim Harris 941813869d8SAlexey Marchuk /* I/O connect when admin qpair is being destroyed */ 942813869d8SAlexey Marchuk admin_qpair.group = NULL; 943813869d8SAlexey Marchuk admin_qpair.state = SPDK_NVMF_QPAIR_DEACTIVATING; 944813869d8SAlexey Marchuk memset(&rsp, 0, sizeof(rsp)); 945312a9d60SBen Walker sgroups[subsystem.id].mgmt_io_outstanding++; 946813869d8SAlexey Marchuk TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 947*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 948813869d8SAlexey Marchuk rc = nvmf_ctrlr_cmd_connect(&req); 949813869d8SAlexey Marchuk poll_threads(); 950813869d8SAlexey Marchuk CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 951813869d8SAlexey Marchuk CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 952813869d8SAlexey Marchuk CU_ASSERT(qpair.ctrlr == NULL); 953312a9d60SBen Walker CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 954813869d8SAlexey Marchuk admin_qpair.group = &group; 955db221b40SKonrad Sztyber admin_qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 956813869d8SAlexey Marchuk 957cc2f6634SZiv Hirsch /* I/O connect when admin qpair was destroyed */ 958cc2f6634SZiv Hirsch ctrlr.admin_qpair = NULL; 959cc2f6634SZiv Hirsch memset(&rsp, 0, sizeof(rsp)); 960cc2f6634SZiv Hirsch sgroups[subsystem.id].mgmt_io_outstanding++; 961cc2f6634SZiv Hirsch TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 962*c2471e45SAlexey Marchuk group.current_unassociated_qpairs = 1; 963cc2f6634SZiv Hirsch rc = nvmf_ctrlr_cmd_connect(&req); 964cc2f6634SZiv Hirsch poll_threads(); 965cc2f6634SZiv Hirsch CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 966cc2f6634SZiv Hirsch CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 967cc2f6634SZiv Hirsch CU_ASSERT(qpair.ctrlr == NULL); 968cc2f6634SZiv Hirsch CU_ASSERT(sgroups[subsystem.id].mgmt_io_outstanding == 0); 969cc2f6634SZiv Hirsch ctrlr.admin_qpair = &admin_qpair; 970cc2f6634SZiv Hirsch 971fab9349fSDaniel Verkamp /* Clean up globals */ 972f56b2300SBen Walker MOCK_CLEAR(spdk_nvmf_tgt_find_subsystem); 973f56b2300SBen Walker MOCK_CLEAR(spdk_nvmf_poll_group_create); 974f08cea71SBen Walker 975f08cea71SBen Walker spdk_bit_array_free(&ctrlr.qpair_mask); 9768fc9ac7bSJinYu free(sgroups); 977fab9349fSDaniel Verkamp } 978fab9349fSDaniel Verkamp 9795c2952abSDaniel Verkamp static void 9805c2952abSDaniel Verkamp test_get_ns_id_desc_list(void) 9815c2952abSDaniel Verkamp { 9825c2952abSDaniel Verkamp struct spdk_nvmf_subsystem subsystem; 9835c2952abSDaniel Verkamp struct spdk_nvmf_qpair qpair; 9845c2952abSDaniel Verkamp struct spdk_nvmf_ctrlr ctrlr; 9855c2952abSDaniel Verkamp struct spdk_nvmf_request req; 9865c2952abSDaniel Verkamp struct spdk_nvmf_ns *ns_ptrs[1]; 9875c2952abSDaniel Verkamp struct spdk_nvmf_ns ns; 9885c2952abSDaniel Verkamp union nvmf_h2c_msg cmd; 9895c2952abSDaniel Verkamp union nvmf_c2h_msg rsp; 9905c2952abSDaniel Verkamp struct spdk_bdev bdev; 9915c2952abSDaniel Verkamp uint8_t buf[4096]; 9925c2952abSDaniel Verkamp 9935c2952abSDaniel Verkamp memset(&subsystem, 0, sizeof(subsystem)); 9945c2952abSDaniel Verkamp ns_ptrs[0] = &ns; 9955c2952abSDaniel Verkamp subsystem.ns = ns_ptrs; 9965c2952abSDaniel Verkamp subsystem.max_nsid = 1; 9975c2952abSDaniel Verkamp subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 9985c2952abSDaniel Verkamp 9995c2952abSDaniel Verkamp memset(&ns, 0, sizeof(ns)); 10005c2952abSDaniel Verkamp ns.opts.nsid = 1; 10015c2952abSDaniel Verkamp ns.bdev = &bdev; 10025c2952abSDaniel Verkamp 10035c2952abSDaniel Verkamp memset(&qpair, 0, sizeof(qpair)); 10045c2952abSDaniel Verkamp qpair.ctrlr = &ctrlr; 10055c2952abSDaniel Verkamp 10065c2952abSDaniel Verkamp memset(&ctrlr, 0, sizeof(ctrlr)); 10075c2952abSDaniel Verkamp ctrlr.subsys = &subsystem; 10085c2952abSDaniel Verkamp ctrlr.vcprop.cc.bits.en = 1; 1009fcc426bdSJacek Kalwas ctrlr.thread = spdk_get_thread(); 1010d37555b4SJonas Pfefferle ctrlr.visible_ns = spdk_bit_array_create(1); 10115c2952abSDaniel Verkamp 10125c2952abSDaniel Verkamp memset(&req, 0, sizeof(req)); 10135c2952abSDaniel Verkamp req.qpair = &qpair; 10145c2952abSDaniel Verkamp req.cmd = &cmd; 10155c2952abSDaniel Verkamp req.rsp = &rsp; 10165c2952abSDaniel Verkamp req.xfer = SPDK_NVME_DATA_CONTROLLER_TO_HOST; 10175c2952abSDaniel Verkamp req.length = sizeof(buf); 1018f029b824SJacek Kalwas SPDK_IOV_ONE(req.iov, &req.iovcnt, &buf, req.length); 10195c2952abSDaniel Verkamp 10205c2952abSDaniel Verkamp memset(&cmd, 0, sizeof(cmd)); 10215c2952abSDaniel Verkamp cmd.nvme_cmd.opc = SPDK_NVME_OPC_IDENTIFY; 10221fea1fccSChangpeng Liu cmd.nvme_cmd.cdw10_bits.identify.cns = SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST; 10235c2952abSDaniel Verkamp 10245c2952abSDaniel Verkamp /* Invalid NSID */ 10255c2952abSDaniel Verkamp cmd.nvme_cmd.nsid = 0; 10265c2952abSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 10279cb21ad6SSeth Howell CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 10285c2952abSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 10295c2952abSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 10305c2952abSDaniel Verkamp 1031d37555b4SJonas Pfefferle /* Valid NSID, but ns is inactive */ 1032d37555b4SJonas Pfefferle spdk_bit_array_clear(ctrlr.visible_ns, 0); 1033d37555b4SJonas Pfefferle cmd.nvme_cmd.nsid = 1; 1034d37555b4SJonas Pfefferle memset(&rsp, 0, sizeof(rsp)); 1035d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1036d37555b4SJonas Pfefferle CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1037d37555b4SJonas Pfefferle CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 1038d37555b4SJonas Pfefferle 10395c2952abSDaniel Verkamp /* Valid NSID, but ns has no IDs defined */ 1040d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 0); 10415c2952abSDaniel Verkamp cmd.nvme_cmd.nsid = 1; 10425c2952abSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 10439cb21ad6SSeth Howell CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 10445c2952abSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 10455c2952abSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 10465c2952abSDaniel Verkamp CU_ASSERT(spdk_mem_all_zero(buf, sizeof(buf))); 10475c2952abSDaniel Verkamp 10488bbc7b69SPawel Baldysiak /* Valid NSID, but command not using NSID */ 10498bbc7b69SPawel Baldysiak cmd.nvme_cmd.opc = SPDK_NVME_OPC_KEEP_ALIVE; 10508bbc7b69SPawel Baldysiak memset(&rsp, 0, sizeof(rsp)); 10518bbc7b69SPawel Baldysiak CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 10528bbc7b69SPawel Baldysiak CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 10538bbc7b69SPawel Baldysiak CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 10548bbc7b69SPawel Baldysiak cmd.nvme_cmd.opc = SPDK_NVME_OPC_IDENTIFY; 10558bbc7b69SPawel Baldysiak 10565c2952abSDaniel Verkamp /* Valid NSID, only EUI64 defined */ 10575c2952abSDaniel Verkamp ns.opts.eui64[0] = 0x11; 10585c2952abSDaniel Verkamp ns.opts.eui64[7] = 0xFF; 10595c2952abSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 10609cb21ad6SSeth Howell CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 10615c2952abSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 10625c2952abSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 10635c2952abSDaniel Verkamp CU_ASSERT(buf[0] == SPDK_NVME_NIDT_EUI64); 10645c2952abSDaniel Verkamp CU_ASSERT(buf[1] == 8); 10655c2952abSDaniel Verkamp CU_ASSERT(buf[4] == 0x11); 10665c2952abSDaniel Verkamp CU_ASSERT(buf[11] == 0xFF); 10675c2952abSDaniel Verkamp CU_ASSERT(buf[13] == 0); 10685c2952abSDaniel Verkamp 10695c2952abSDaniel Verkamp /* Valid NSID, only NGUID defined */ 10705c2952abSDaniel Verkamp memset(ns.opts.eui64, 0, sizeof(ns.opts.eui64)); 10715c2952abSDaniel Verkamp ns.opts.nguid[0] = 0x22; 10725c2952abSDaniel Verkamp ns.opts.nguid[15] = 0xEE; 10735c2952abSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 10749cb21ad6SSeth Howell CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 10755c2952abSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 10765c2952abSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 10775c2952abSDaniel Verkamp CU_ASSERT(buf[0] == SPDK_NVME_NIDT_NGUID); 10785c2952abSDaniel Verkamp CU_ASSERT(buf[1] == 16); 10795c2952abSDaniel Verkamp CU_ASSERT(buf[4] == 0x22); 10805c2952abSDaniel Verkamp CU_ASSERT(buf[19] == 0xEE); 10815c2952abSDaniel Verkamp CU_ASSERT(buf[21] == 0); 10825c2952abSDaniel Verkamp 10835c2952abSDaniel Verkamp /* Valid NSID, both EUI64 and NGUID defined */ 10845c2952abSDaniel Verkamp ns.opts.eui64[0] = 0x11; 10855c2952abSDaniel Verkamp ns.opts.eui64[7] = 0xFF; 10865c2952abSDaniel Verkamp ns.opts.nguid[0] = 0x22; 10875c2952abSDaniel Verkamp ns.opts.nguid[15] = 0xEE; 10885c2952abSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 10899cb21ad6SSeth Howell CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 10905c2952abSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 10915c2952abSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 10925c2952abSDaniel Verkamp CU_ASSERT(buf[0] == SPDK_NVME_NIDT_EUI64); 10935c2952abSDaniel Verkamp CU_ASSERT(buf[1] == 8); 10945c2952abSDaniel Verkamp CU_ASSERT(buf[4] == 0x11); 10955c2952abSDaniel Verkamp CU_ASSERT(buf[11] == 0xFF); 10965c2952abSDaniel Verkamp CU_ASSERT(buf[12] == SPDK_NVME_NIDT_NGUID); 10975c2952abSDaniel Verkamp CU_ASSERT(buf[13] == 16); 10985c2952abSDaniel Verkamp CU_ASSERT(buf[16] == 0x22); 10995c2952abSDaniel Verkamp CU_ASSERT(buf[31] == 0xEE); 11005c2952abSDaniel Verkamp CU_ASSERT(buf[33] == 0); 1101a05f88ffSDaniel Verkamp 1102a05f88ffSDaniel Verkamp /* Valid NSID, EUI64, NGUID, and UUID defined */ 1103a05f88ffSDaniel Verkamp ns.opts.eui64[0] = 0x11; 1104a05f88ffSDaniel Verkamp ns.opts.eui64[7] = 0xFF; 1105a05f88ffSDaniel Verkamp ns.opts.nguid[0] = 0x22; 1106a05f88ffSDaniel Verkamp ns.opts.nguid[15] = 0xEE; 1107a05f88ffSDaniel Verkamp ns.opts.uuid.u.raw[0] = 0x33; 1108a05f88ffSDaniel Verkamp ns.opts.uuid.u.raw[15] = 0xDD; 1109a05f88ffSDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 11109cb21ad6SSeth Howell CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1111a05f88ffSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1112a05f88ffSDaniel Verkamp CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 1113a05f88ffSDaniel Verkamp CU_ASSERT(buf[0] == SPDK_NVME_NIDT_EUI64); 1114a05f88ffSDaniel Verkamp CU_ASSERT(buf[1] == 8); 1115a05f88ffSDaniel Verkamp CU_ASSERT(buf[4] == 0x11); 1116a05f88ffSDaniel Verkamp CU_ASSERT(buf[11] == 0xFF); 1117a05f88ffSDaniel Verkamp CU_ASSERT(buf[12] == SPDK_NVME_NIDT_NGUID); 1118a05f88ffSDaniel Verkamp CU_ASSERT(buf[13] == 16); 1119a05f88ffSDaniel Verkamp CU_ASSERT(buf[16] == 0x22); 1120a05f88ffSDaniel Verkamp CU_ASSERT(buf[31] == 0xEE); 1121a05f88ffSDaniel Verkamp CU_ASSERT(buf[32] == SPDK_NVME_NIDT_UUID); 1122a05f88ffSDaniel Verkamp CU_ASSERT(buf[33] == 16); 1123a05f88ffSDaniel Verkamp CU_ASSERT(buf[36] == 0x33); 1124a05f88ffSDaniel Verkamp CU_ASSERT(buf[51] == 0xDD); 1125a05f88ffSDaniel Verkamp CU_ASSERT(buf[53] == 0); 1126d37555b4SJonas Pfefferle 1127d37555b4SJonas Pfefferle spdk_bit_array_free(&ctrlr.visible_ns); 11285c2952abSDaniel Verkamp } 11295c2952abSDaniel Verkamp 1130a35b1eb6SDaniel Verkamp static void 1131a35b1eb6SDaniel Verkamp test_identify_ns(void) 1132a35b1eb6SDaniel Verkamp { 1133a35b1eb6SDaniel Verkamp struct spdk_nvmf_subsystem subsystem = {}; 1134acca82acSPiotr Pelplinski struct spdk_nvmf_transport transport = {}; 1135acca82acSPiotr Pelplinski struct spdk_nvmf_qpair admin_qpair = { .transport = &transport}; 1136d37555b4SJonas Pfefferle struct spdk_nvmf_ctrlr ctrlr = { 1137d37555b4SJonas Pfefferle .subsys = &subsystem, 1138d37555b4SJonas Pfefferle .admin_qpair = &admin_qpair, 1139d37555b4SJonas Pfefferle }; 1140a35b1eb6SDaniel Verkamp struct spdk_nvme_cmd cmd = {}; 1141a35b1eb6SDaniel Verkamp struct spdk_nvme_cpl rsp = {}; 1142a35b1eb6SDaniel Verkamp struct spdk_nvme_ns_data nsdata = {}; 1143a35b1eb6SDaniel Verkamp struct spdk_bdev bdev[3] = {{.blockcnt = 1234}, {.blockcnt = 0}, {.blockcnt = 5678}}; 1144a35b1eb6SDaniel Verkamp struct spdk_nvmf_ns ns[3] = {{.bdev = &bdev[0]}, {.bdev = NULL}, {.bdev = &bdev[2]}}; 1145a35b1eb6SDaniel Verkamp struct spdk_nvmf_ns *ns_arr[3] = {&ns[0], NULL, &ns[2]}; 1146a35b1eb6SDaniel Verkamp 1147d37555b4SJonas Pfefferle ctrlr.visible_ns = spdk_bit_array_create(3); 1148d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 0); 1149d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 2); 1150d37555b4SJonas Pfefferle 1151a35b1eb6SDaniel Verkamp subsystem.ns = ns_arr; 1152a35b1eb6SDaniel Verkamp subsystem.max_nsid = SPDK_COUNTOF(ns_arr); 1153a35b1eb6SDaniel Verkamp 1154a35b1eb6SDaniel Verkamp /* Invalid NSID 0 */ 1155a35b1eb6SDaniel Verkamp cmd.nsid = 0; 1156a35b1eb6SDaniel Verkamp memset(&nsdata, 0, sizeof(nsdata)); 1157a35b1eb6SDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 1158ddb17216SPiotr Pelplinski CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 1159a35b1eb6SDaniel Verkamp &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1160a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1161a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 1162a35b1eb6SDaniel Verkamp CU_ASSERT(spdk_mem_all_zero(&nsdata, sizeof(nsdata))); 1163a35b1eb6SDaniel Verkamp 1164a35b1eb6SDaniel Verkamp /* Valid NSID 1 */ 1165a35b1eb6SDaniel Verkamp cmd.nsid = 1; 1166a35b1eb6SDaniel Verkamp memset(&nsdata, 0, sizeof(nsdata)); 1167a35b1eb6SDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 1168ddb17216SPiotr Pelplinski CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 1169a35b1eb6SDaniel Verkamp &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1170a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1171a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 1172a35b1eb6SDaniel Verkamp CU_ASSERT(nsdata.nsze == 1234); 1173a35b1eb6SDaniel Verkamp 1174d37555b4SJonas Pfefferle /* Valid but inactive NSID 1 */ 1175d37555b4SJonas Pfefferle spdk_bit_array_clear(ctrlr.visible_ns, 0); 1176d37555b4SJonas Pfefferle cmd.nsid = 1; 1177d37555b4SJonas Pfefferle memset(&nsdata, 0, sizeof(nsdata)); 1178d37555b4SJonas Pfefferle memset(&rsp, 0, sizeof(rsp)); 1179d37555b4SJonas Pfefferle CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 1180d37555b4SJonas Pfefferle &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1181d37555b4SJonas Pfefferle CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1182d37555b4SJonas Pfefferle CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 1183d37555b4SJonas Pfefferle CU_ASSERT(spdk_mem_all_zero(&nsdata, sizeof(nsdata))); 1184d37555b4SJonas Pfefferle 1185d37555b4SJonas Pfefferle /* Valid but unallocated NSID 2 */ 1186a35b1eb6SDaniel Verkamp cmd.nsid = 2; 1187a35b1eb6SDaniel Verkamp memset(&nsdata, 0, sizeof(nsdata)); 1188a35b1eb6SDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 1189ddb17216SPiotr Pelplinski CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 1190a35b1eb6SDaniel Verkamp &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1191a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1192a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 1193a35b1eb6SDaniel Verkamp CU_ASSERT(spdk_mem_all_zero(&nsdata, sizeof(nsdata))); 1194a35b1eb6SDaniel Verkamp 1195a35b1eb6SDaniel Verkamp /* Valid NSID 3 */ 1196a35b1eb6SDaniel Verkamp cmd.nsid = 3; 1197a35b1eb6SDaniel Verkamp memset(&nsdata, 0, sizeof(nsdata)); 1198a35b1eb6SDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 1199ddb17216SPiotr Pelplinski CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 1200a35b1eb6SDaniel Verkamp &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1201a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1202a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 1203a35b1eb6SDaniel Verkamp CU_ASSERT(nsdata.nsze == 5678); 1204a35b1eb6SDaniel Verkamp 1205a35b1eb6SDaniel Verkamp /* Invalid NSID 4 */ 1206a35b1eb6SDaniel Verkamp cmd.nsid = 4; 1207a35b1eb6SDaniel Verkamp memset(&nsdata, 0, sizeof(nsdata)); 1208a35b1eb6SDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 1209ddb17216SPiotr Pelplinski CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 1210a35b1eb6SDaniel Verkamp &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1211a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1212a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 1213a35b1eb6SDaniel Verkamp CU_ASSERT(spdk_mem_all_zero(&nsdata, sizeof(nsdata))); 1214a35b1eb6SDaniel Verkamp 1215a35b1eb6SDaniel Verkamp /* Invalid NSID 0xFFFFFFFF (NS management not supported) */ 1216a35b1eb6SDaniel Verkamp cmd.nsid = 0xFFFFFFFF; 1217a35b1eb6SDaniel Verkamp memset(&nsdata, 0, sizeof(nsdata)); 1218a35b1eb6SDaniel Verkamp memset(&rsp, 0, sizeof(rsp)); 1219ddb17216SPiotr Pelplinski CU_ASSERT(spdk_nvmf_ctrlr_identify_ns(&ctrlr, &cmd, &rsp, 1220a35b1eb6SDaniel Verkamp &nsdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1221a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1222a35b1eb6SDaniel Verkamp CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 1223a35b1eb6SDaniel Verkamp CU_ASSERT(spdk_mem_all_zero(&nsdata, sizeof(nsdata))); 1224d37555b4SJonas Pfefferle 1225d37555b4SJonas Pfefferle spdk_bit_array_free(&ctrlr.visible_ns); 1226a35b1eb6SDaniel Verkamp } 1227a35b1eb6SDaniel Verkamp 12285f5a5d4aSChangpeng Liu static void 1229a36785dfSDennis Maisenbacher test_identify_ns_iocs_specific(void) 1230a36785dfSDennis Maisenbacher { 1231a36785dfSDennis Maisenbacher struct spdk_nvmf_subsystem subsystem = {}; 1232a36785dfSDennis Maisenbacher struct spdk_nvmf_transport transport = {}; 1233a36785dfSDennis Maisenbacher struct spdk_nvmf_qpair admin_qpair = { .transport = &transport }; 1234a36785dfSDennis Maisenbacher struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsystem, .admin_qpair = &admin_qpair }; 1235a36785dfSDennis Maisenbacher struct spdk_nvme_cmd cmd = {}; 1236a36785dfSDennis Maisenbacher struct spdk_nvme_cpl rsp = {}; 12375e4d957eSShuhei Matsumoto struct spdk_nvme_zns_ns_data nsdata_zns = {}; 12385e4d957eSShuhei Matsumoto struct spdk_nvme_nvm_ns_data nsdata_nvm = {}; 1239a36785dfSDennis Maisenbacher struct spdk_bdev bdev[2] = {{.blockcnt = 1234, .zoned = true, .zone_size = ZONE_SIZE, .max_open_zones = MAX_OPEN_ZONES, .max_active_zones = MAX_ACTIVE_ZONES}, {.blockcnt = 5678}}; 1240a36785dfSDennis Maisenbacher struct spdk_nvmf_ns ns[2] = {{.bdev = &bdev[0]}, {.bdev = &bdev[1]}}; 1241a36785dfSDennis Maisenbacher struct spdk_nvmf_ns *ns_arr[2] = {&ns[0], &ns[1]}; 1242a36785dfSDennis Maisenbacher 1243d37555b4SJonas Pfefferle ctrlr.visible_ns = spdk_bit_array_create(3); 1244d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 0); 1245d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 1); 1246d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 2); 1247a36785dfSDennis Maisenbacher subsystem.ns = ns_arr; 1248a36785dfSDennis Maisenbacher subsystem.max_nsid = SPDK_COUNTOF(ns_arr); 1249a36785dfSDennis Maisenbacher 1250a36785dfSDennis Maisenbacher cmd.cdw11_bits.identify.csi = SPDK_NVME_CSI_ZNS; 1251a36785dfSDennis Maisenbacher 1252a36785dfSDennis Maisenbacher /* Invalid ZNS NSID 0 */ 1253a36785dfSDennis Maisenbacher cmd.nsid = 0; 12545e4d957eSShuhei Matsumoto memset(&nsdata_zns, 0xFF, sizeof(nsdata_zns)); 1255a36785dfSDennis Maisenbacher memset(&rsp, 0, sizeof(rsp)); 1256a36785dfSDennis Maisenbacher CU_ASSERT(spdk_nvmf_ns_identify_iocs_specific(&ctrlr, &cmd, &rsp, 12575e4d957eSShuhei Matsumoto &nsdata_zns, sizeof(nsdata_zns)) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1258a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1259a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 12605e4d957eSShuhei Matsumoto CU_ASSERT(spdk_mem_all_zero(&nsdata_zns, sizeof(nsdata_zns))); 1261a36785dfSDennis Maisenbacher 1262a36785dfSDennis Maisenbacher /* Valid ZNS NSID 1 */ 1263a36785dfSDennis Maisenbacher cmd.nsid = 1; 12645e4d957eSShuhei Matsumoto memset(&nsdata_zns, 0xFF, sizeof(nsdata_zns)); 1265a36785dfSDennis Maisenbacher memset(&rsp, 0, sizeof(rsp)); 1266a36785dfSDennis Maisenbacher CU_ASSERT(spdk_nvmf_ns_identify_iocs_specific(&ctrlr, &cmd, &rsp, 12675e4d957eSShuhei Matsumoto &nsdata_zns, sizeof(nsdata_zns)) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1268a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1269a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 12705e4d957eSShuhei Matsumoto CU_ASSERT(nsdata_zns.ozcs.read_across_zone_boundaries == 1); 12715e4d957eSShuhei Matsumoto CU_ASSERT(nsdata_zns.mar == MAX_ACTIVE_ZONES - 1); 12725e4d957eSShuhei Matsumoto CU_ASSERT(nsdata_zns.mor == MAX_OPEN_ZONES - 1); 12735e4d957eSShuhei Matsumoto CU_ASSERT(nsdata_zns.lbafe[0].zsze == ZONE_SIZE); 12745e4d957eSShuhei Matsumoto nsdata_zns.ozcs.read_across_zone_boundaries = 0; 12755e4d957eSShuhei Matsumoto nsdata_zns.mar = 0; 12765e4d957eSShuhei Matsumoto nsdata_zns.mor = 0; 12775e4d957eSShuhei Matsumoto nsdata_zns.lbafe[0].zsze = 0; 12785e4d957eSShuhei Matsumoto CU_ASSERT(spdk_mem_all_zero(&nsdata_zns, sizeof(nsdata_zns))); 1279a36785dfSDennis Maisenbacher 1280a36785dfSDennis Maisenbacher cmd.cdw11_bits.identify.csi = SPDK_NVME_CSI_NVM; 1281a36785dfSDennis Maisenbacher 12825e4d957eSShuhei Matsumoto /* Valid NVM NSID 2 with DIF type 1 */ 12835e4d957eSShuhei Matsumoto bdev[1].dif_type = SPDK_DIF_TYPE1; 1284a36785dfSDennis Maisenbacher cmd.nsid = 2; 12855e4d957eSShuhei Matsumoto memset(&nsdata_nvm, 0xFF, sizeof(nsdata_nvm)); 1286a36785dfSDennis Maisenbacher memset(&rsp, 0, sizeof(rsp)); 1287a36785dfSDennis Maisenbacher CU_ASSERT(spdk_nvmf_ns_identify_iocs_specific(&ctrlr, &cmd, &rsp, 12885e4d957eSShuhei Matsumoto &nsdata_nvm, sizeof(nsdata_nvm)) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1289a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1290a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 12915e4d957eSShuhei Matsumoto CU_ASSERT(nsdata_nvm.lbstm == 0); 12925e4d957eSShuhei Matsumoto CU_ASSERT(nsdata_nvm.pic._16bpists == 0); 12935e4d957eSShuhei Matsumoto CU_ASSERT(nsdata_nvm.pic._16bpistm == 1); 12945e4d957eSShuhei Matsumoto CU_ASSERT(nsdata_nvm.pic.stcrs == 0); 12955e4d957eSShuhei Matsumoto CU_ASSERT(nsdata_nvm.elbaf[0].sts == 16); 12965e4d957eSShuhei Matsumoto CU_ASSERT(nsdata_nvm.elbaf[0].pif == SPDK_DIF_PI_FORMAT_32); 12975e4d957eSShuhei Matsumoto nsdata_nvm.pic._16bpistm = 0; 12985e4d957eSShuhei Matsumoto nsdata_nvm.elbaf[0].sts = 0; 12995e4d957eSShuhei Matsumoto nsdata_nvm.elbaf[0].pif = 0; 13005e4d957eSShuhei Matsumoto CU_ASSERT(spdk_mem_all_zero(&nsdata_nvm, sizeof(nsdata_nvm))); 1301a36785dfSDennis Maisenbacher 1302a36785dfSDennis Maisenbacher /* Invalid NVM NSID 3 */ 1303a36785dfSDennis Maisenbacher cmd.nsid = 0; 13045e4d957eSShuhei Matsumoto memset(&nsdata_nvm, 0xFF, sizeof(nsdata_nvm)); 1305a36785dfSDennis Maisenbacher memset(&rsp, 0, sizeof(rsp)); 1306a36785dfSDennis Maisenbacher CU_ASSERT(spdk_nvmf_ns_identify_iocs_specific(&ctrlr, &cmd, &rsp, 13075e4d957eSShuhei Matsumoto &nsdata_nvm, sizeof(nsdata_nvm)) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1308a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1309a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 13105e4d957eSShuhei Matsumoto CU_ASSERT(spdk_mem_all_zero(&nsdata_nvm, sizeof(nsdata_nvm))); 1311d37555b4SJonas Pfefferle 1312d37555b4SJonas Pfefferle spdk_bit_array_free(&ctrlr.visible_ns); 1313a36785dfSDennis Maisenbacher } 1314a36785dfSDennis Maisenbacher 1315a36785dfSDennis Maisenbacher static void 13165f5a5d4aSChangpeng Liu test_set_get_features(void) 13175f5a5d4aSChangpeng Liu { 13185f5a5d4aSChangpeng Liu struct spdk_nvmf_subsystem subsystem = {}; 13195f5a5d4aSChangpeng Liu struct spdk_nvmf_qpair admin_qpair = {}; 1320785d10b5SShuhei Matsumoto enum spdk_nvme_ana_state ana_state[3]; 1321785d10b5SShuhei Matsumoto struct spdk_nvmf_subsystem_listener listener = { .ana_state = ana_state }; 132268f16817SShuhei Matsumoto struct spdk_nvmf_ctrlr ctrlr = { 1323d37555b4SJonas Pfefferle .subsys = &subsystem, 1324d37555b4SJonas Pfefferle .admin_qpair = &admin_qpair, 1325d37555b4SJonas Pfefferle .listener = &listener 132668f16817SShuhei Matsumoto }; 13275f5a5d4aSChangpeng Liu union nvmf_h2c_msg cmd = {}; 13285f5a5d4aSChangpeng Liu union nvmf_c2h_msg rsp = {}; 13295f5a5d4aSChangpeng Liu struct spdk_nvmf_ns ns[3]; 1330785d10b5SShuhei Matsumoto struct spdk_nvmf_ns *ns_arr[3] = {&ns[0], NULL, &ns[2]}; 13315f5a5d4aSChangpeng Liu struct spdk_nvmf_request req; 13325f5a5d4aSChangpeng Liu int rc; 13335f5a5d4aSChangpeng Liu 1334d37555b4SJonas Pfefferle ctrlr.visible_ns = spdk_bit_array_create(3); 1335d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 0); 1336d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 2); 133707bfc3cbSShuhei Matsumoto ns[0].anagrpid = 1; 133807bfc3cbSShuhei Matsumoto ns[2].anagrpid = 3; 13395f5a5d4aSChangpeng Liu subsystem.ns = ns_arr; 13405f5a5d4aSChangpeng Liu subsystem.max_nsid = SPDK_COUNTOF(ns_arr); 1341785d10b5SShuhei Matsumoto listener.ana_state[0] = SPDK_NVME_ANA_OPTIMIZED_STATE; 1342785d10b5SShuhei Matsumoto listener.ana_state[2] = SPDK_NVME_ANA_OPTIMIZED_STATE; 13435f5a5d4aSChangpeng Liu admin_qpair.ctrlr = &ctrlr; 13445f5a5d4aSChangpeng Liu req.qpair = &admin_qpair; 13455f5a5d4aSChangpeng Liu cmd.nvme_cmd.nsid = 1; 13465f5a5d4aSChangpeng Liu req.cmd = &cmd; 13475f5a5d4aSChangpeng Liu req.rsp = &rsp; 13485f5a5d4aSChangpeng Liu 13495f5a5d4aSChangpeng Liu /* Set SPDK_NVME_FEAT_HOST_RESERVE_PERSIST feature */ 13505f5a5d4aSChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 13510c9057f0SChangpeng Liu cmd.nvme_cmd.cdw11_bits.feat_rsv_persistence.bits.ptpl = 1; 13525f5a5d4aSChangpeng Liu ns[0].ptpl_file = "testcfg"; 1353198fd2ceSSeth Howell rc = nvmf_ctrlr_set_features_reservation_persistence(&req); 13545f5a5d4aSChangpeng Liu CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 13555f5a5d4aSChangpeng Liu CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 13565f5a5d4aSChangpeng Liu CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_FEATURE_ID_NOT_SAVEABLE); 13575f5a5d4aSChangpeng Liu CU_ASSERT(ns[0].ptpl_activated == true); 13585f5a5d4aSChangpeng Liu 13595f5a5d4aSChangpeng Liu /* Get SPDK_NVME_FEAT_HOST_RESERVE_PERSIST feature */ 13605f5a5d4aSChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_FEATURES; 13611fea1fccSChangpeng Liu cmd.nvme_cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_HOST_RESERVE_PERSIST; 1362198fd2ceSSeth Howell rc = nvmf_ctrlr_get_features_reservation_persistence(&req); 13635f5a5d4aSChangpeng Liu CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 13645f5a5d4aSChangpeng Liu CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 13655f5a5d4aSChangpeng Liu CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 13665f5a5d4aSChangpeng Liu CU_ASSERT(rsp.nvme_cpl.cdw0 == 1); 1367c0fb1b93SMichal Berger 1368c0fb1b93SMichal Berger 1369c0fb1b93SMichal Berger /* Get SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD - valid TMPSEL */ 1370c0fb1b93SMichal Berger cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_FEATURES; 1371c0fb1b93SMichal Berger cmd.nvme_cmd.cdw11 = 0x42; 1372c0fb1b93SMichal Berger cmd.nvme_cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD; 1373c0fb1b93SMichal Berger 1374198fd2ceSSeth Howell rc = nvmf_ctrlr_get_features(&req); 1375c0fb1b93SMichal Berger CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1376c0fb1b93SMichal Berger 1377c0fb1b93SMichal Berger /* Get SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD - invalid TMPSEL */ 1378c0fb1b93SMichal Berger cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_FEATURES; 1379c0fb1b93SMichal Berger cmd.nvme_cmd.cdw11 = 0x42 | 1 << 16 | 1 << 19; /* Set reserved value */ 1380c0fb1b93SMichal Berger cmd.nvme_cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD; 1381c0fb1b93SMichal Berger 1382198fd2ceSSeth Howell rc = nvmf_ctrlr_get_features(&req); 1383c0fb1b93SMichal Berger CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1384c0fb1b93SMichal Berger CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1385c0fb1b93SMichal Berger CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 1386c0fb1b93SMichal Berger 1387c0fb1b93SMichal Berger /* Set SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD - valid TMPSEL */ 1388c0fb1b93SMichal Berger cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1389c0fb1b93SMichal Berger cmd.nvme_cmd.cdw11 = 0x42; 1390c0fb1b93SMichal Berger cmd.nvme_cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD; 1391c0fb1b93SMichal Berger 1392198fd2ceSSeth Howell rc = nvmf_ctrlr_set_features(&req); 1393c0fb1b93SMichal Berger CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1394c0fb1b93SMichal Berger 1395c0fb1b93SMichal Berger /* Set SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD - invalid TMPSEL */ 1396c0fb1b93SMichal Berger cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1397c0fb1b93SMichal Berger cmd.nvme_cmd.cdw11 = 0x42 | 1 << 16 | 1 << 19; /* Set reserved value */ 1398c0fb1b93SMichal Berger cmd.nvme_cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD; 1399c0fb1b93SMichal Berger 1400198fd2ceSSeth Howell rc = nvmf_ctrlr_set_features(&req); 1401c0fb1b93SMichal Berger CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1402c0fb1b93SMichal Berger CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1403c0fb1b93SMichal Berger CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 1404c0fb1b93SMichal Berger 1405c0fb1b93SMichal Berger /* Set SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD - invalid THSEL */ 1406c0fb1b93SMichal Berger cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1407c0fb1b93SMichal Berger cmd.nvme_cmd.cdw11 = 0x42; 1408c0fb1b93SMichal Berger cmd.nvme_cmd.cdw11_bits.feat_temp_threshold.bits.thsel = 0x3; /* Set reserved value */ 1409c0fb1b93SMichal Berger cmd.nvme_cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD; 1410c0fb1b93SMichal Berger 1411198fd2ceSSeth Howell rc = nvmf_ctrlr_set_features(&req); 1412c0fb1b93SMichal Berger CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1413c0fb1b93SMichal Berger CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1414c0fb1b93SMichal Berger CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 1415c0fb1b93SMichal Berger 1416c0fb1b93SMichal Berger 1417c0fb1b93SMichal Berger /* get SPDK_NVME_FEAT_ERROR_RECOVERY - generic */ 1418c0fb1b93SMichal Berger cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1419c0fb1b93SMichal Berger cmd.nvme_cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_ERROR_RECOVERY; 1420c0fb1b93SMichal Berger 1421198fd2ceSSeth Howell rc = nvmf_ctrlr_get_features(&req); 1422c0fb1b93SMichal Berger CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1423c0fb1b93SMichal Berger 1424c0fb1b93SMichal Berger /* Set SPDK_NVME_FEAT_ERROR_RECOVERY - DULBE set */ 1425c0fb1b93SMichal Berger cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1426c0fb1b93SMichal Berger cmd.nvme_cmd.cdw11 = 0x42; 1427c0fb1b93SMichal Berger cmd.nvme_cmd.cdw11_bits.feat_error_recovery.bits.dulbe = 0x1; 1428c0fb1b93SMichal Berger cmd.nvme_cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_ERROR_RECOVERY; 1429c0fb1b93SMichal Berger 1430198fd2ceSSeth Howell rc = nvmf_ctrlr_set_features(&req); 1431c0fb1b93SMichal Berger CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1432c0fb1b93SMichal Berger CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1433c0fb1b93SMichal Berger CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 1434c0fb1b93SMichal Berger 1435c0fb1b93SMichal Berger /* Set SPDK_NVME_FEAT_ERROR_RECOVERY - DULBE cleared */ 1436c0fb1b93SMichal Berger cmd.nvme_cmd.opc = SPDK_NVME_OPC_SET_FEATURES; 1437c0fb1b93SMichal Berger cmd.nvme_cmd.cdw11 = 0x42; 1438c0fb1b93SMichal Berger cmd.nvme_cmd.cdw11_bits.feat_error_recovery.bits.dulbe = 0x0; 1439c0fb1b93SMichal Berger cmd.nvme_cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_ERROR_RECOVERY; 1440c0fb1b93SMichal Berger 1441198fd2ceSSeth Howell rc = nvmf_ctrlr_set_features(&req); 1442c0fb1b93SMichal Berger CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1443d37555b4SJonas Pfefferle 1444d37555b4SJonas Pfefferle spdk_bit_array_free(&ctrlr.visible_ns); 14455f5a5d4aSChangpeng Liu } 14465f5a5d4aSChangpeng Liu 144724e012c0SChangpeng Liu /* 144824e012c0SChangpeng Liu * Reservation Unit Test Configuration 144924e012c0SChangpeng Liu * -------- -------- -------- 145024e012c0SChangpeng Liu * | Host A | | Host B | | Host C | 145124e012c0SChangpeng Liu * -------- -------- -------- 145224e012c0SChangpeng Liu * / \ | | 145324e012c0SChangpeng Liu * -------- -------- ------- ------- 145424e012c0SChangpeng Liu * |Ctrlr1_A| |Ctrlr2_A| |Ctrlr_B| |Ctrlr_C| 145524e012c0SChangpeng Liu * -------- -------- ------- ------- 145624e012c0SChangpeng Liu * \ \ / / 145724e012c0SChangpeng Liu * \ \ / / 145824e012c0SChangpeng Liu * \ \ / / 145924e012c0SChangpeng Liu * -------------------------------------- 146024e012c0SChangpeng Liu * | NAMESPACE 1 | 146124e012c0SChangpeng Liu * -------------------------------------- 146224e012c0SChangpeng Liu */ 146324e012c0SChangpeng Liu 146424e012c0SChangpeng Liu static struct spdk_nvmf_ctrlr g_ctrlr1_A, g_ctrlr2_A, g_ctrlr_B, g_ctrlr_C; 146524e012c0SChangpeng Liu struct spdk_nvmf_subsystem_pg_ns_info g_ns_info; 146624e012c0SChangpeng Liu 146724e012c0SChangpeng Liu static void 146824e012c0SChangpeng Liu ut_reservation_init(enum spdk_nvme_reservation_type rtype) 146924e012c0SChangpeng Liu { 147024e012c0SChangpeng Liu /* Host A has two controllers */ 147124e012c0SChangpeng Liu spdk_uuid_generate(&g_ctrlr1_A.hostid); 147224e012c0SChangpeng Liu spdk_uuid_copy(&g_ctrlr2_A.hostid, &g_ctrlr1_A.hostid); 147324e012c0SChangpeng Liu 147424e012c0SChangpeng Liu /* Host B has 1 controller */ 147524e012c0SChangpeng Liu spdk_uuid_generate(&g_ctrlr_B.hostid); 147624e012c0SChangpeng Liu 147724e012c0SChangpeng Liu /* Host C has 1 controller */ 147824e012c0SChangpeng Liu spdk_uuid_generate(&g_ctrlr_C.hostid); 147924e012c0SChangpeng Liu 148024e012c0SChangpeng Liu memset(&g_ns_info, 0, sizeof(g_ns_info)); 148124e012c0SChangpeng Liu g_ns_info.rtype = rtype; 148224e012c0SChangpeng Liu g_ns_info.reg_hostid[0] = g_ctrlr1_A.hostid; 148324e012c0SChangpeng Liu g_ns_info.reg_hostid[1] = g_ctrlr_B.hostid; 148424e012c0SChangpeng Liu g_ns_info.reg_hostid[2] = g_ctrlr_C.hostid; 148524e012c0SChangpeng Liu } 148624e012c0SChangpeng Liu 148724e012c0SChangpeng Liu static void 148824e012c0SChangpeng Liu test_reservation_write_exclusive(void) 148924e012c0SChangpeng Liu { 149024e012c0SChangpeng Liu struct spdk_nvmf_request req = {}; 149124e012c0SChangpeng Liu union nvmf_h2c_msg cmd = {}; 149224e012c0SChangpeng Liu union nvmf_c2h_msg rsp = {}; 149324e012c0SChangpeng Liu int rc; 149424e012c0SChangpeng Liu 149524e012c0SChangpeng Liu req.cmd = &cmd; 149624e012c0SChangpeng Liu req.rsp = &rsp; 149724e012c0SChangpeng Liu 149824e012c0SChangpeng Liu /* Host A holds reservation with type SPDK_NVME_RESERVE_WRITE_EXCLUSIVE */ 149924e012c0SChangpeng Liu ut_reservation_init(SPDK_NVME_RESERVE_WRITE_EXCLUSIVE); 150024e012c0SChangpeng Liu g_ns_info.holder_id = g_ctrlr1_A.hostid; 150124e012c0SChangpeng Liu 150224e012c0SChangpeng Liu /* Test Case: Issue a Read command from Host A and Host B */ 150324e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 150424e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req); 150524e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 150624e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 150724e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 150824e012c0SChangpeng Liu 150924e012c0SChangpeng Liu /* Test Case: Issue a DSM Write command from Host A and Host B */ 151024e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_DATASET_MANAGEMENT; 151124e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req); 151224e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 151324e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 151424e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc < 0); 151524e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 151624e012c0SChangpeng Liu 151724e012c0SChangpeng Liu /* Test Case: Issue a Write command from Host C */ 151824e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 151924e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 152024e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc < 0); 152124e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 152224e012c0SChangpeng Liu 152324e012c0SChangpeng Liu /* Test Case: Issue a Read command from Host B */ 152424e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 152524e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 152624e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 152724e012c0SChangpeng Liu 152824e012c0SChangpeng Liu /* Unregister Host C */ 152995a367d6SArtur Paszkiewicz spdk_uuid_set_null(&g_ns_info.reg_hostid[2]); 153024e012c0SChangpeng Liu 153124e012c0SChangpeng Liu /* Test Case: Read and Write commands from non-registrant Host C */ 153224e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 153324e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 153424e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc < 0); 153524e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 153624e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 153724e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 153824e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 153924e012c0SChangpeng Liu } 154024e012c0SChangpeng Liu 154124e012c0SChangpeng Liu static void 154224e012c0SChangpeng Liu test_reservation_exclusive_access(void) 154324e012c0SChangpeng Liu { 154424e012c0SChangpeng Liu struct spdk_nvmf_request req = {}; 154524e012c0SChangpeng Liu union nvmf_h2c_msg cmd = {}; 154624e012c0SChangpeng Liu union nvmf_c2h_msg rsp = {}; 154724e012c0SChangpeng Liu int rc; 154824e012c0SChangpeng Liu 154924e012c0SChangpeng Liu req.cmd = &cmd; 155024e012c0SChangpeng Liu req.rsp = &rsp; 155124e012c0SChangpeng Liu 155224e012c0SChangpeng Liu /* Host A holds reservation with type SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS */ 155324e012c0SChangpeng Liu ut_reservation_init(SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS); 155424e012c0SChangpeng Liu g_ns_info.holder_id = g_ctrlr1_A.hostid; 155524e012c0SChangpeng Liu 155624e012c0SChangpeng Liu /* Test Case: Issue a Read command from Host B */ 155724e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 155824e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 155924e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc < 0); 156024e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 156124e012c0SChangpeng Liu 156224e012c0SChangpeng Liu /* Test Case: Issue a Reservation Release command from a valid Registrant */ 156324e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_RESERVATION_RELEASE; 156424e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 156524e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 156624e012c0SChangpeng Liu } 156724e012c0SChangpeng Liu 156824e012c0SChangpeng Liu static void 156924e012c0SChangpeng Liu _test_reservation_write_exclusive_regs_only_and_all_regs(enum spdk_nvme_reservation_type rtype) 157024e012c0SChangpeng Liu { 157124e012c0SChangpeng Liu struct spdk_nvmf_request req = {}; 157224e012c0SChangpeng Liu union nvmf_h2c_msg cmd = {}; 157324e012c0SChangpeng Liu union nvmf_c2h_msg rsp = {}; 157424e012c0SChangpeng Liu int rc; 157524e012c0SChangpeng Liu 157624e012c0SChangpeng Liu req.cmd = &cmd; 157724e012c0SChangpeng Liu req.rsp = &rsp; 157824e012c0SChangpeng Liu 157924e012c0SChangpeng Liu /* SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY and SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS */ 158024e012c0SChangpeng Liu ut_reservation_init(rtype); 158124e012c0SChangpeng Liu g_ns_info.holder_id = g_ctrlr1_A.hostid; 158224e012c0SChangpeng Liu 158324e012c0SChangpeng Liu /* Test Case: Issue a Read command from Host A and Host C */ 158424e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 158524e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req); 158624e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 158724e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 158824e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 158924e012c0SChangpeng Liu 159024e012c0SChangpeng Liu /* Test Case: Issue a DSM Write command from Host A and Host C */ 159124e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_DATASET_MANAGEMENT; 159224e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr1_A, &req); 159324e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 159424e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 159524e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 159624e012c0SChangpeng Liu 159724e012c0SChangpeng Liu /* Unregister Host C */ 159895a367d6SArtur Paszkiewicz spdk_uuid_set_null(&g_ns_info.reg_hostid[2]); 159924e012c0SChangpeng Liu 160024e012c0SChangpeng Liu /* Test Case: Read and Write commands from non-registrant Host C */ 160124e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 160224e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 160324e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 160424e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 160524e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_C, &req); 160624e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc < 0); 160724e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 160824e012c0SChangpeng Liu } 160924e012c0SChangpeng Liu 161024e012c0SChangpeng Liu static void 161124e012c0SChangpeng Liu test_reservation_write_exclusive_regs_only_and_all_regs(void) 161224e012c0SChangpeng Liu { 161324e012c0SChangpeng Liu _test_reservation_write_exclusive_regs_only_and_all_regs( 161424e012c0SChangpeng Liu SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY); 161524e012c0SChangpeng Liu _test_reservation_write_exclusive_regs_only_and_all_regs( 161624e012c0SChangpeng Liu SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS); 161724e012c0SChangpeng Liu } 161824e012c0SChangpeng Liu 161924e012c0SChangpeng Liu static void 162024e012c0SChangpeng Liu _test_reservation_exclusive_access_regs_only_and_all_regs(enum spdk_nvme_reservation_type rtype) 162124e012c0SChangpeng Liu { 162224e012c0SChangpeng Liu struct spdk_nvmf_request req = {}; 162324e012c0SChangpeng Liu union nvmf_h2c_msg cmd = {}; 162424e012c0SChangpeng Liu union nvmf_c2h_msg rsp = {}; 162524e012c0SChangpeng Liu int rc; 162624e012c0SChangpeng Liu 162724e012c0SChangpeng Liu req.cmd = &cmd; 162824e012c0SChangpeng Liu req.rsp = &rsp; 162924e012c0SChangpeng Liu 163024e012c0SChangpeng Liu /* SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY and SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS */ 163124e012c0SChangpeng Liu ut_reservation_init(rtype); 163224e012c0SChangpeng Liu g_ns_info.holder_id = g_ctrlr1_A.hostid; 163324e012c0SChangpeng Liu 163424e012c0SChangpeng Liu /* Test Case: Issue a Write command from Host B */ 163524e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 163624e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 163724e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc == 0); 163824e012c0SChangpeng Liu 163924e012c0SChangpeng Liu /* Unregister Host B */ 164095a367d6SArtur Paszkiewicz spdk_uuid_set_null(&g_ns_info.reg_hostid[1]); 164124e012c0SChangpeng Liu 164224e012c0SChangpeng Liu /* Test Case: Issue a Read command from Host B */ 164324e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 164424e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 164524e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc < 0); 164624e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 164724e012c0SChangpeng Liu cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 164824e012c0SChangpeng Liu rc = nvmf_ns_reservation_request_check(&g_ns_info, &g_ctrlr_B, &req); 164924e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rc < 0); 165024e012c0SChangpeng Liu SPDK_CU_ASSERT_FATAL(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_RESERVATION_CONFLICT); 165124e012c0SChangpeng Liu } 165224e012c0SChangpeng Liu 165324e012c0SChangpeng Liu static void 165424e012c0SChangpeng Liu test_reservation_exclusive_access_regs_only_and_all_regs(void) 165524e012c0SChangpeng Liu { 165624e012c0SChangpeng Liu _test_reservation_exclusive_access_regs_only_and_all_regs( 165724e012c0SChangpeng Liu SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY); 165824e012c0SChangpeng Liu _test_reservation_exclusive_access_regs_only_and_all_regs( 165924e012c0SChangpeng Liu SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS); 166024e012c0SChangpeng Liu } 166124e012c0SChangpeng Liu 16623b214eb8SChangpeng Liu static void 16638cd9ef28SJiewei Ke init_pending_async_events(struct spdk_nvmf_ctrlr *ctrlr) 16648cd9ef28SJiewei Ke { 16658cd9ef28SJiewei Ke STAILQ_INIT(&ctrlr->async_events); 16668cd9ef28SJiewei Ke } 16678cd9ef28SJiewei Ke 16688cd9ef28SJiewei Ke static void 16698cd9ef28SJiewei Ke cleanup_pending_async_events(struct spdk_nvmf_ctrlr *ctrlr) 16708cd9ef28SJiewei Ke { 16718cd9ef28SJiewei Ke struct spdk_nvmf_async_event_completion *event, *event_tmp; 16728cd9ef28SJiewei Ke 16738cd9ef28SJiewei Ke STAILQ_FOREACH_SAFE(event, &ctrlr->async_events, link, event_tmp) { 16748cd9ef28SJiewei Ke STAILQ_REMOVE(&ctrlr->async_events, event, spdk_nvmf_async_event_completion, link); 16758cd9ef28SJiewei Ke free(event); 16768cd9ef28SJiewei Ke } 16778cd9ef28SJiewei Ke } 16788cd9ef28SJiewei Ke 1679a9bdb1eeSJiewei Ke static int 1680a9bdb1eeSJiewei Ke num_pending_async_events(struct spdk_nvmf_ctrlr *ctrlr) 1681a9bdb1eeSJiewei Ke { 1682a9bdb1eeSJiewei Ke int num = 0; 1683a9bdb1eeSJiewei Ke struct spdk_nvmf_async_event_completion *event; 1684a9bdb1eeSJiewei Ke 1685a9bdb1eeSJiewei Ke STAILQ_FOREACH(event, &ctrlr->async_events, link) { 1686a9bdb1eeSJiewei Ke num++; 1687a9bdb1eeSJiewei Ke } 1688a9bdb1eeSJiewei Ke return num; 1689a9bdb1eeSJiewei Ke } 1690a9bdb1eeSJiewei Ke 16918cd9ef28SJiewei Ke static void 16923b214eb8SChangpeng Liu test_reservation_notification_log_page(void) 16933b214eb8SChangpeng Liu { 16943b214eb8SChangpeng Liu struct spdk_nvmf_ctrlr ctrlr; 16953b214eb8SChangpeng Liu struct spdk_nvmf_qpair qpair; 16963b214eb8SChangpeng Liu struct spdk_nvmf_ns ns; 1697785246f9SEvgeniy Kochetov struct spdk_nvmf_request req = {}; 16985e1b30bdSRichael Zhuang union nvmf_h2c_msg cmd = {}; 16995e1b30bdSRichael Zhuang union nvmf_c2h_msg rsp = {}; 17005e1b30bdSRichael Zhuang union spdk_nvme_async_event_completion event = {}; 17013b214eb8SChangpeng Liu struct spdk_nvme_reservation_notification_log logs[3]; 1702adc2942aSJiewei Ke struct iovec iov; 17033b214eb8SChangpeng Liu 17043b214eb8SChangpeng Liu memset(&ctrlr, 0, sizeof(ctrlr)); 17053b214eb8SChangpeng Liu ctrlr.thread = spdk_get_thread(); 17063b214eb8SChangpeng Liu TAILQ_INIT(&ctrlr.log_head); 17078cd9ef28SJiewei Ke init_pending_async_events(&ctrlr); 17083b214eb8SChangpeng Liu ns.nsid = 1; 17093b214eb8SChangpeng Liu 17103b214eb8SChangpeng Liu /* Test Case: Mask all the reservation notifications */ 17113b214eb8SChangpeng Liu ns.mask = SPDK_NVME_REGISTRATION_PREEMPTED_MASK | 17123b214eb8SChangpeng Liu SPDK_NVME_RESERVATION_RELEASED_MASK | 17133b214eb8SChangpeng Liu SPDK_NVME_RESERVATION_PREEMPTED_MASK; 17149cb21ad6SSeth Howell nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 17153b214eb8SChangpeng Liu SPDK_NVME_REGISTRATION_PREEMPTED); 17169cb21ad6SSeth Howell nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 17173b214eb8SChangpeng Liu SPDK_NVME_RESERVATION_RELEASED); 17189cb21ad6SSeth Howell nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 17193b214eb8SChangpeng Liu SPDK_NVME_RESERVATION_PREEMPTED); 17203b214eb8SChangpeng Liu poll_threads(); 17213b214eb8SChangpeng Liu SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&ctrlr.log_head)); 17223b214eb8SChangpeng Liu 17233b214eb8SChangpeng Liu /* Test Case: Unmask all the reservation notifications, 17243b214eb8SChangpeng Liu * 3 log pages are generated, and AER was triggered. 17253b214eb8SChangpeng Liu */ 17263b214eb8SChangpeng Liu ns.mask = 0; 17273b214eb8SChangpeng Liu ctrlr.num_avail_log_pages = 0; 17283b214eb8SChangpeng Liu req.cmd = &cmd; 17293b214eb8SChangpeng Liu req.rsp = &rsp; 1730b7cc4dd7SJin Yu ctrlr.aer_req[0] = &req; 1731b7cc4dd7SJin Yu ctrlr.nr_aer_reqs = 1; 17323b214eb8SChangpeng Liu req.qpair = &qpair; 17333b214eb8SChangpeng Liu TAILQ_INIT(&qpair.outstanding); 17348fc9ac7bSJinYu qpair.ctrlr = NULL; 1735781d42adSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_ENABLED; 17363b214eb8SChangpeng Liu TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 17373b214eb8SChangpeng Liu 17389cb21ad6SSeth Howell nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 17393b214eb8SChangpeng Liu SPDK_NVME_REGISTRATION_PREEMPTED); 17409cb21ad6SSeth Howell nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 17413b214eb8SChangpeng Liu SPDK_NVME_RESERVATION_RELEASED); 17429cb21ad6SSeth Howell nvmf_ctrlr_reservation_notice_log(&ctrlr, &ns, 17433b214eb8SChangpeng Liu SPDK_NVME_RESERVATION_PREEMPTED); 17443b214eb8SChangpeng Liu poll_threads(); 17453b214eb8SChangpeng Liu event.raw = rsp.nvme_cpl.cdw0; 17463b214eb8SChangpeng Liu SPDK_CU_ASSERT_FATAL(event.bits.async_event_type == SPDK_NVME_ASYNC_EVENT_TYPE_IO); 17473b214eb8SChangpeng Liu SPDK_CU_ASSERT_FATAL(event.bits.async_event_info == SPDK_NVME_ASYNC_EVENT_RESERVATION_LOG_AVAIL); 17483b214eb8SChangpeng Liu SPDK_CU_ASSERT_FATAL(event.bits.log_page_identifier == SPDK_NVME_LOG_RESERVATION_NOTIFICATION); 17493b214eb8SChangpeng Liu SPDK_CU_ASSERT_FATAL(ctrlr.num_avail_log_pages == 3); 17503b214eb8SChangpeng Liu 17513b214eb8SChangpeng Liu /* Test Case: Get Log Page to clear the log pages */ 1752adc2942aSJiewei Ke iov.iov_base = &logs[0]; 1753adc2942aSJiewei Ke iov.iov_len = sizeof(logs); 1754adc2942aSJiewei Ke nvmf_get_reservation_notification_log_page(&ctrlr, &iov, 1, 0, sizeof(logs), 0); 17553b214eb8SChangpeng Liu SPDK_CU_ASSERT_FATAL(ctrlr.num_avail_log_pages == 0); 17568cd9ef28SJiewei Ke 17578cd9ef28SJiewei Ke cleanup_pending_async_events(&ctrlr); 17583b214eb8SChangpeng Liu } 17593b214eb8SChangpeng Liu 1760ddb680ebSShuhei Matsumoto static void 1761ddb680ebSShuhei Matsumoto test_get_dif_ctx(void) 1762ddb680ebSShuhei Matsumoto { 1763ddb680ebSShuhei Matsumoto struct spdk_nvmf_subsystem subsystem = {}; 1764ddb680ebSShuhei Matsumoto struct spdk_nvmf_request req = {}; 1765ddb680ebSShuhei Matsumoto struct spdk_nvmf_qpair qpair = {}; 1766ddb680ebSShuhei Matsumoto struct spdk_nvmf_ctrlr ctrlr = {}; 1767ddb680ebSShuhei Matsumoto struct spdk_nvmf_ns ns = {}; 1768ddb680ebSShuhei Matsumoto struct spdk_nvmf_ns *_ns = NULL; 1769ddb680ebSShuhei Matsumoto struct spdk_bdev bdev = {}; 1770ddb680ebSShuhei Matsumoto union nvmf_h2c_msg cmd = {}; 1771ddb680ebSShuhei Matsumoto struct spdk_dif_ctx dif_ctx = {}; 1772ddb680ebSShuhei Matsumoto bool ret; 1773ddb680ebSShuhei Matsumoto 1774ddb680ebSShuhei Matsumoto ctrlr.subsys = &subsystem; 1775d37555b4SJonas Pfefferle ctrlr.visible_ns = spdk_bit_array_create(1); 1776d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 0); 1777ddb680ebSShuhei Matsumoto 1778ddb680ebSShuhei Matsumoto qpair.ctrlr = &ctrlr; 1779ddb680ebSShuhei Matsumoto 1780ddb680ebSShuhei Matsumoto req.qpair = &qpair; 1781ddb680ebSShuhei Matsumoto req.cmd = &cmd; 1782ddb680ebSShuhei Matsumoto 1783ddb680ebSShuhei Matsumoto ns.bdev = &bdev; 1784ddb680ebSShuhei Matsumoto 17854ff3665cSShuhei Matsumoto ctrlr.dif_insert_or_strip = false; 17864ff3665cSShuhei Matsumoto 17874ff3665cSShuhei Matsumoto ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 17884ff3665cSShuhei Matsumoto CU_ASSERT(ret == false); 17894ff3665cSShuhei Matsumoto 17904ff3665cSShuhei Matsumoto ctrlr.dif_insert_or_strip = true; 1791ddb680ebSShuhei Matsumoto qpair.state = SPDK_NVMF_QPAIR_UNINITIALIZED; 1792ddb680ebSShuhei Matsumoto 1793ddb680ebSShuhei Matsumoto ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1794ddb680ebSShuhei Matsumoto CU_ASSERT(ret == false); 1795ddb680ebSShuhei Matsumoto 1796781d42adSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_ENABLED; 1797ddb680ebSShuhei Matsumoto cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_FABRIC; 1798ddb680ebSShuhei Matsumoto 1799ddb680ebSShuhei Matsumoto ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1800ddb680ebSShuhei Matsumoto CU_ASSERT(ret == false); 1801ddb680ebSShuhei Matsumoto 1802ddb680ebSShuhei Matsumoto cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_FLUSH; 1803ddb680ebSShuhei Matsumoto 1804ddb680ebSShuhei Matsumoto ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1805ddb680ebSShuhei Matsumoto CU_ASSERT(ret == false); 1806ddb680ebSShuhei Matsumoto 1807ddb680ebSShuhei Matsumoto qpair.qid = 1; 1808ddb680ebSShuhei Matsumoto 1809ddb680ebSShuhei Matsumoto ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1810ddb680ebSShuhei Matsumoto CU_ASSERT(ret == false); 1811ddb680ebSShuhei Matsumoto 1812ddb680ebSShuhei Matsumoto cmd.nvme_cmd.nsid = 1; 1813ddb680ebSShuhei Matsumoto 1814ddb680ebSShuhei Matsumoto ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1815ddb680ebSShuhei Matsumoto CU_ASSERT(ret == false); 1816ddb680ebSShuhei Matsumoto 1817ddb680ebSShuhei Matsumoto subsystem.max_nsid = 1; 1818ddb680ebSShuhei Matsumoto subsystem.ns = &_ns; 1819ddb680ebSShuhei Matsumoto subsystem.ns[0] = &ns; 1820ddb680ebSShuhei Matsumoto 1821ddb680ebSShuhei Matsumoto ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1822ddb680ebSShuhei Matsumoto CU_ASSERT(ret == false); 1823ddb680ebSShuhei Matsumoto 1824ddb680ebSShuhei Matsumoto cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_WRITE; 1825ddb680ebSShuhei Matsumoto 1826ddb680ebSShuhei Matsumoto ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx); 1827ddb680ebSShuhei Matsumoto CU_ASSERT(ret == true); 1828d37555b4SJonas Pfefferle 1829d37555b4SJonas Pfefferle spdk_bit_array_free(&ctrlr.visible_ns); 1830ddb680ebSShuhei Matsumoto } 1831ddb680ebSShuhei Matsumoto 1832225c74e4SAlexey Marchuk static void 1833225c74e4SAlexey Marchuk test_identify_ctrlr(void) 1834225c74e4SAlexey Marchuk { 1835b832f99fSyupeng struct spdk_nvmf_tgt tgt = {}; 1836225c74e4SAlexey Marchuk struct spdk_nvmf_subsystem subsystem = { 1837b832f99fSyupeng .subtype = SPDK_NVMF_SUBTYPE_NVME, 1838b832f99fSyupeng .tgt = &tgt, 1839225c74e4SAlexey Marchuk }; 1840225c74e4SAlexey Marchuk struct spdk_nvmf_transport_ops tops = {}; 1841225c74e4SAlexey Marchuk struct spdk_nvmf_transport transport = { 1842225c74e4SAlexey Marchuk .ops = &tops, 1843225c74e4SAlexey Marchuk .opts = { 1844225c74e4SAlexey Marchuk .in_capsule_data_size = 4096, 1845225c74e4SAlexey Marchuk }, 1846225c74e4SAlexey Marchuk }; 1847225c74e4SAlexey Marchuk struct spdk_nvmf_qpair admin_qpair = { .transport = &transport}; 1848225c74e4SAlexey Marchuk struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsystem, .admin_qpair = &admin_qpair }; 1849225c74e4SAlexey Marchuk struct spdk_nvme_ctrlr_data cdata = {}; 1850225c74e4SAlexey Marchuk uint32_t expected_ioccsz; 1851225c74e4SAlexey Marchuk 1852000e6f5bSJacek Kalwas nvmf_ctrlr_cdata_init(&transport, &subsystem, &ctrlr.cdata); 1853538f1354SJacek Kalwas 1854225c74e4SAlexey Marchuk /* Check ioccsz, TCP transport */ 1855225c74e4SAlexey Marchuk tops.type = SPDK_NVME_TRANSPORT_TCP; 1856225c74e4SAlexey Marchuk expected_ioccsz = sizeof(struct spdk_nvme_cmd) / 16 + transport.opts.in_capsule_data_size / 16; 1857225c74e4SAlexey Marchuk CU_ASSERT(spdk_nvmf_ctrlr_identify_ctrlr(&ctrlr, &cdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1858225c74e4SAlexey Marchuk CU_ASSERT(cdata.nvmf_specific.ioccsz == expected_ioccsz); 1859225c74e4SAlexey Marchuk 1860225c74e4SAlexey Marchuk /* Check ioccsz, RDMA transport */ 1861225c74e4SAlexey Marchuk tops.type = SPDK_NVME_TRANSPORT_RDMA; 1862225c74e4SAlexey Marchuk expected_ioccsz = sizeof(struct spdk_nvme_cmd) / 16 + transport.opts.in_capsule_data_size / 16; 1863225c74e4SAlexey Marchuk CU_ASSERT(spdk_nvmf_ctrlr_identify_ctrlr(&ctrlr, &cdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1864225c74e4SAlexey Marchuk CU_ASSERT(cdata.nvmf_specific.ioccsz == expected_ioccsz); 1865225c74e4SAlexey Marchuk 1866225c74e4SAlexey Marchuk /* Check ioccsz, TCP transport with dif_insert_or_strip */ 1867225c74e4SAlexey Marchuk tops.type = SPDK_NVME_TRANSPORT_TCP; 1868225c74e4SAlexey Marchuk ctrlr.dif_insert_or_strip = true; 1869225c74e4SAlexey Marchuk expected_ioccsz = sizeof(struct spdk_nvme_cmd) / 16 + transport.opts.in_capsule_data_size / 16; 1870225c74e4SAlexey Marchuk CU_ASSERT(spdk_nvmf_ctrlr_identify_ctrlr(&ctrlr, &cdata) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1871225c74e4SAlexey Marchuk CU_ASSERT(cdata.nvmf_specific.ioccsz == expected_ioccsz); 1872225c74e4SAlexey Marchuk } 1873225c74e4SAlexey Marchuk 1874a36785dfSDennis Maisenbacher static void 1875a36785dfSDennis Maisenbacher test_identify_ctrlr_iocs_specific(void) 1876a36785dfSDennis Maisenbacher { 1877a36785dfSDennis Maisenbacher struct spdk_nvmf_subsystem subsystem = { .max_zone_append_size_kib = 0 }; 1878a36785dfSDennis Maisenbacher struct spdk_nvmf_registers vcprop = { .cap.bits.mpsmin = 0 }; 1879a36785dfSDennis Maisenbacher struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsystem, .vcprop = vcprop }; 1880a36785dfSDennis Maisenbacher struct spdk_nvme_cmd cmd = {}; 1881a36785dfSDennis Maisenbacher struct spdk_nvme_cpl rsp = {}; 1882a36785dfSDennis Maisenbacher struct spdk_nvme_zns_ctrlr_data ctrlr_data = {}; 1883c7feb85dSHaoqian He struct spdk_nvme_nvm_ctrlr_data cdata_nvm = {}; 1884a36785dfSDennis Maisenbacher 1885a36785dfSDennis Maisenbacher cmd.cdw11_bits.identify.csi = SPDK_NVME_CSI_ZNS; 1886a36785dfSDennis Maisenbacher 1887a36785dfSDennis Maisenbacher /* ZNS max_zone_append_size_kib no limit */ 1888a36785dfSDennis Maisenbacher memset(&ctrlr_data, 0xFF, sizeof(ctrlr_data)); 1889a36785dfSDennis Maisenbacher memset(&rsp, 0, sizeof(rsp)); 1890a36785dfSDennis Maisenbacher CU_ASSERT(spdk_nvmf_ctrlr_identify_iocs_specific(&ctrlr, &cmd, &rsp, 1891a36785dfSDennis Maisenbacher &ctrlr_data, sizeof(ctrlr_data)) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1892a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1893a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 1894a36785dfSDennis Maisenbacher CU_ASSERT(ctrlr_data.zasl == 0); 1895a36785dfSDennis Maisenbacher CU_ASSERT(spdk_mem_all_zero(&ctrlr_data, sizeof(ctrlr_data))); 1896a36785dfSDennis Maisenbacher 1897a36785dfSDennis Maisenbacher /* ZNS max_zone_append_size_kib = 4096 */ 1898a36785dfSDennis Maisenbacher memset(&ctrlr_data, 0xFF, sizeof(ctrlr_data)); 1899a36785dfSDennis Maisenbacher memset(&rsp, 0, sizeof(rsp)); 1900a36785dfSDennis Maisenbacher subsystem.max_zone_append_size_kib = 4096; 1901a36785dfSDennis Maisenbacher CU_ASSERT(spdk_nvmf_ctrlr_identify_iocs_specific(&ctrlr, &cmd, &rsp, 1902a36785dfSDennis Maisenbacher &ctrlr_data, sizeof(ctrlr_data)) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1903a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1904a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 1905a36785dfSDennis Maisenbacher CU_ASSERT(ctrlr_data.zasl == 0); 1906a36785dfSDennis Maisenbacher CU_ASSERT(spdk_mem_all_zero(&ctrlr_data, sizeof(ctrlr_data))); 1907a36785dfSDennis Maisenbacher 1908a36785dfSDennis Maisenbacher /* ZNS max_zone_append_size_kib = 60000 */ 1909a36785dfSDennis Maisenbacher memset(&ctrlr_data, 0xFF, sizeof(ctrlr_data)); 1910a36785dfSDennis Maisenbacher memset(&rsp, 0, sizeof(rsp)); 1911a36785dfSDennis Maisenbacher subsystem.max_zone_append_size_kib = 60000; 1912a36785dfSDennis Maisenbacher CU_ASSERT(spdk_nvmf_ctrlr_identify_iocs_specific(&ctrlr, &cmd, &rsp, 1913a36785dfSDennis Maisenbacher &ctrlr_data, sizeof(ctrlr_data)) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1914a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1915a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 1916a36785dfSDennis Maisenbacher CU_ASSERT(ctrlr_data.zasl == 3); 1917a36785dfSDennis Maisenbacher ctrlr_data.zasl = 0; 1918a36785dfSDennis Maisenbacher CU_ASSERT(spdk_mem_all_zero(&ctrlr_data, sizeof(ctrlr_data))); 1919a36785dfSDennis Maisenbacher 1920a36785dfSDennis Maisenbacher /* ZNS max_zone_append_size_kib = 60000; mpsmin = 2 */ 1921a36785dfSDennis Maisenbacher memset(&ctrlr_data, 0xFF, sizeof(ctrlr_data)); 1922a36785dfSDennis Maisenbacher memset(&rsp, 0, sizeof(rsp)); 1923a36785dfSDennis Maisenbacher ctrlr.vcprop.cap.bits.mpsmin = 2; 1924a36785dfSDennis Maisenbacher subsystem.max_zone_append_size_kib = 60000; 1925a36785dfSDennis Maisenbacher CU_ASSERT(spdk_nvmf_ctrlr_identify_iocs_specific(&ctrlr, &cmd, &rsp, 1926a36785dfSDennis Maisenbacher &ctrlr_data, sizeof(ctrlr_data)) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1927a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1928a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 1929a36785dfSDennis Maisenbacher CU_ASSERT(ctrlr_data.zasl == 1); 1930a36785dfSDennis Maisenbacher ctrlr_data.zasl = 0; 1931a36785dfSDennis Maisenbacher CU_ASSERT(spdk_mem_all_zero(&ctrlr_data, sizeof(ctrlr_data))); 1932a36785dfSDennis Maisenbacher ctrlr.vcprop.cap.bits.mpsmin = 0; 1933a36785dfSDennis Maisenbacher 1934a36785dfSDennis Maisenbacher cmd.cdw11_bits.identify.csi = SPDK_NVME_CSI_NVM; 1935a36785dfSDennis Maisenbacher 1936c7feb85dSHaoqian He /* NVM max_discard_size_kib = 1024; 1937c7feb85dSHaoqian He * max_write_zeroes_size_kib = 1024; 1938c7feb85dSHaoqian He * mpsmin = 0; 1939c7feb85dSHaoqian He */ 1940c7feb85dSHaoqian He memset(&cdata_nvm, 0xFF, sizeof(cdata_nvm)); 1941a36785dfSDennis Maisenbacher memset(&rsp, 0, sizeof(rsp)); 1942c7feb85dSHaoqian He subsystem.max_discard_size_kib = (uint64_t)1024; 1943c7feb85dSHaoqian He subsystem.max_write_zeroes_size_kib = (uint64_t)1024; 1944a36785dfSDennis Maisenbacher CU_ASSERT(spdk_nvmf_ctrlr_identify_iocs_specific(&ctrlr, &cmd, &rsp, 1945c7feb85dSHaoqian He &cdata_nvm, sizeof(cdata_nvm)) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 1946a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sct == SPDK_NVME_SCT_GENERIC); 1947a36785dfSDennis Maisenbacher CU_ASSERT(rsp.status.sc == SPDK_NVME_SC_SUCCESS); 1948c7feb85dSHaoqian He CU_ASSERT(cdata_nvm.wzsl == 8); 1949c7feb85dSHaoqian He CU_ASSERT(cdata_nvm.dmrsl == 2048); 1950c7feb85dSHaoqian He CU_ASSERT(cdata_nvm.dmrl == 1); 1951a36785dfSDennis Maisenbacher } 1952a36785dfSDennis Maisenbacher 19533fa22056SMichael Haeuptle static int 19543fa22056SMichael Haeuptle custom_admin_cmd_hdlr(struct spdk_nvmf_request *req) 19553fa22056SMichael Haeuptle { 19563fa22056SMichael Haeuptle req->rsp->nvme_cpl.status.sc = SPDK_NVME_SC_SUCCESS; 19573fa22056SMichael Haeuptle 19583fa22056SMichael Haeuptle return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 19593fa22056SMichael Haeuptle }; 19603fa22056SMichael Haeuptle 19613fa22056SMichael Haeuptle static void 19623fa22056SMichael Haeuptle test_custom_admin_cmd(void) 19633fa22056SMichael Haeuptle { 19643fa22056SMichael Haeuptle struct spdk_nvmf_subsystem subsystem; 19653fa22056SMichael Haeuptle struct spdk_nvmf_qpair qpair; 19663fa22056SMichael Haeuptle struct spdk_nvmf_ctrlr ctrlr; 19673fa22056SMichael Haeuptle struct spdk_nvmf_request req; 19683fa22056SMichael Haeuptle struct spdk_nvmf_ns *ns_ptrs[1]; 19693fa22056SMichael Haeuptle struct spdk_nvmf_ns ns; 19703fa22056SMichael Haeuptle union nvmf_h2c_msg cmd; 19713fa22056SMichael Haeuptle union nvmf_c2h_msg rsp; 19723fa22056SMichael Haeuptle struct spdk_bdev bdev; 19733fa22056SMichael Haeuptle uint8_t buf[4096]; 19743fa22056SMichael Haeuptle int rc; 19753fa22056SMichael Haeuptle 19763fa22056SMichael Haeuptle memset(&subsystem, 0, sizeof(subsystem)); 19773fa22056SMichael Haeuptle ns_ptrs[0] = &ns; 19783fa22056SMichael Haeuptle subsystem.ns = ns_ptrs; 19793fa22056SMichael Haeuptle subsystem.max_nsid = 1; 19803fa22056SMichael Haeuptle subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 19813fa22056SMichael Haeuptle 19823fa22056SMichael Haeuptle memset(&ns, 0, sizeof(ns)); 19833fa22056SMichael Haeuptle ns.opts.nsid = 1; 19843fa22056SMichael Haeuptle ns.bdev = &bdev; 19853fa22056SMichael Haeuptle 19863fa22056SMichael Haeuptle memset(&qpair, 0, sizeof(qpair)); 19873fa22056SMichael Haeuptle qpair.ctrlr = &ctrlr; 19883fa22056SMichael Haeuptle 19893fa22056SMichael Haeuptle memset(&ctrlr, 0, sizeof(ctrlr)); 19903fa22056SMichael Haeuptle ctrlr.subsys = &subsystem; 19913fa22056SMichael Haeuptle ctrlr.vcprop.cc.bits.en = 1; 1992fcc426bdSJacek Kalwas ctrlr.thread = spdk_get_thread(); 19933fa22056SMichael Haeuptle 19943fa22056SMichael Haeuptle memset(&req, 0, sizeof(req)); 19953fa22056SMichael Haeuptle req.qpair = &qpair; 19963fa22056SMichael Haeuptle req.cmd = &cmd; 19973fa22056SMichael Haeuptle req.rsp = &rsp; 19983fa22056SMichael Haeuptle req.xfer = SPDK_NVME_DATA_CONTROLLER_TO_HOST; 19993fa22056SMichael Haeuptle req.length = sizeof(buf); 2000f029b824SJacek Kalwas SPDK_IOV_ONE(req.iov, &req.iovcnt, &buf, req.length); 20013fa22056SMichael Haeuptle 20023fa22056SMichael Haeuptle memset(&cmd, 0, sizeof(cmd)); 20033fa22056SMichael Haeuptle cmd.nvme_cmd.opc = 0xc1; 20043fa22056SMichael Haeuptle cmd.nvme_cmd.nsid = 0; 20053fa22056SMichael Haeuptle memset(&rsp, 0, sizeof(rsp)); 20063fa22056SMichael Haeuptle 20073fa22056SMichael Haeuptle spdk_nvmf_set_custom_admin_cmd_hdlr(cmd.nvme_cmd.opc, custom_admin_cmd_hdlr); 20083fa22056SMichael Haeuptle 20093fa22056SMichael Haeuptle /* Ensure that our hdlr is being called */ 20109cb21ad6SSeth Howell rc = nvmf_ctrlr_process_admin_cmd(&req); 20113fa22056SMichael Haeuptle CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 20123fa22056SMichael Haeuptle CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 20133fa22056SMichael Haeuptle CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 20143fa22056SMichael Haeuptle } 20153fa22056SMichael Haeuptle 201698bbb72dSTomasz Kulasek static void 201798bbb72dSTomasz Kulasek test_fused_compare_and_write(void) 201898bbb72dSTomasz Kulasek { 20195e1b30bdSRichael Zhuang struct spdk_nvmf_request req = {}; 20205e1b30bdSRichael Zhuang struct spdk_nvmf_qpair qpair = {}; 20215e1b30bdSRichael Zhuang struct spdk_nvme_cmd cmd = {}; 20225e1b30bdSRichael Zhuang union nvmf_c2h_msg rsp = {}; 20235e1b30bdSRichael Zhuang struct spdk_nvmf_ctrlr ctrlr = {}; 20245e1b30bdSRichael Zhuang struct spdk_nvmf_subsystem subsystem = {}; 20255e1b30bdSRichael Zhuang struct spdk_nvmf_ns ns = {}; 20265e1b30bdSRichael Zhuang struct spdk_nvmf_ns *subsys_ns[1] = {}; 2027785d10b5SShuhei Matsumoto enum spdk_nvme_ana_state ana_state[1]; 2028785d10b5SShuhei Matsumoto struct spdk_nvmf_subsystem_listener listener = { .ana_state = ana_state }; 20295e1b30bdSRichael Zhuang struct spdk_bdev bdev = {}; 203098bbb72dSTomasz Kulasek 20315e1b30bdSRichael Zhuang struct spdk_nvmf_poll_group group = {}; 20325e1b30bdSRichael Zhuang struct spdk_nvmf_subsystem_poll_group sgroups = {}; 20335e1b30bdSRichael Zhuang struct spdk_nvmf_subsystem_pg_ns_info ns_info = {}; 2034312a9d60SBen Walker struct spdk_io_channel io_ch = {}; 203598bbb72dSTomasz Kulasek 203698bbb72dSTomasz Kulasek ns.bdev = &bdev; 203707bfc3cbSShuhei Matsumoto ns.anagrpid = 1; 203898bbb72dSTomasz Kulasek 203998bbb72dSTomasz Kulasek subsystem.id = 0; 204098bbb72dSTomasz Kulasek subsystem.max_nsid = 1; 204198bbb72dSTomasz Kulasek subsys_ns[0] = &ns; 204298bbb72dSTomasz Kulasek subsystem.ns = (struct spdk_nvmf_ns **)&subsys_ns; 204398bbb72dSTomasz Kulasek 2044785d10b5SShuhei Matsumoto listener.ana_state[0] = SPDK_NVME_ANA_OPTIMIZED_STATE; 204568f16817SShuhei Matsumoto 204698bbb72dSTomasz Kulasek /* Enable controller */ 204798bbb72dSTomasz Kulasek ctrlr.vcprop.cc.bits.en = 1; 204898bbb72dSTomasz Kulasek ctrlr.subsys = (struct spdk_nvmf_subsystem *)&subsystem; 204968f16817SShuhei Matsumoto ctrlr.listener = &listener; 2050d37555b4SJonas Pfefferle ctrlr.visible_ns = spdk_bit_array_create(1); 2051d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 0); 205298bbb72dSTomasz Kulasek 205398bbb72dSTomasz Kulasek group.num_sgroups = 1; 205498bbb72dSTomasz Kulasek sgroups.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 205598bbb72dSTomasz Kulasek sgroups.num_ns = 1; 2056312a9d60SBen Walker ns_info.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 2057312a9d60SBen Walker ns_info.channel = &io_ch; 205898bbb72dSTomasz Kulasek sgroups.ns_info = &ns_info; 205998bbb72dSTomasz Kulasek TAILQ_INIT(&sgroups.queued); 206098bbb72dSTomasz Kulasek group.sgroups = &sgroups; 206198bbb72dSTomasz Kulasek TAILQ_INIT(&qpair.outstanding); 206298bbb72dSTomasz Kulasek 206398bbb72dSTomasz Kulasek qpair.ctrlr = &ctrlr; 206498bbb72dSTomasz Kulasek qpair.group = &group; 206598bbb72dSTomasz Kulasek qpair.qid = 1; 2066781d42adSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_ENABLED; 206798bbb72dSTomasz Kulasek 206898bbb72dSTomasz Kulasek cmd.nsid = 1; 206998bbb72dSTomasz Kulasek 207098bbb72dSTomasz Kulasek req.qpair = &qpair; 207198bbb72dSTomasz Kulasek req.cmd = (union nvmf_h2c_msg *)&cmd; 207298bbb72dSTomasz Kulasek req.rsp = &rsp; 207398bbb72dSTomasz Kulasek 207498bbb72dSTomasz Kulasek /* SUCCESS/SUCCESS */ 207598bbb72dSTomasz Kulasek cmd.fuse = SPDK_NVME_CMD_FUSE_FIRST; 207698bbb72dSTomasz Kulasek cmd.opc = SPDK_NVME_OPC_COMPARE; 207798bbb72dSTomasz Kulasek 207898bbb72dSTomasz Kulasek spdk_nvmf_request_exec(&req); 207998bbb72dSTomasz Kulasek CU_ASSERT(qpair.first_fused_req != NULL); 208098bbb72dSTomasz Kulasek CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 208198bbb72dSTomasz Kulasek 208298bbb72dSTomasz Kulasek cmd.fuse = SPDK_NVME_CMD_FUSE_SECOND; 208398bbb72dSTomasz Kulasek cmd.opc = SPDK_NVME_OPC_WRITE; 208498bbb72dSTomasz Kulasek 208598bbb72dSTomasz Kulasek spdk_nvmf_request_exec(&req); 208698bbb72dSTomasz Kulasek CU_ASSERT(qpair.first_fused_req == NULL); 208798bbb72dSTomasz Kulasek CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 208898bbb72dSTomasz Kulasek 208998bbb72dSTomasz Kulasek /* Wrong sequence */ 209098bbb72dSTomasz Kulasek cmd.fuse = SPDK_NVME_CMD_FUSE_SECOND; 209198bbb72dSTomasz Kulasek cmd.opc = SPDK_NVME_OPC_WRITE; 209298bbb72dSTomasz Kulasek 209398bbb72dSTomasz Kulasek spdk_nvmf_request_exec(&req); 209498bbb72dSTomasz Kulasek CU_ASSERT(!nvme_status_success(&rsp.nvme_cpl.status)); 209598bbb72dSTomasz Kulasek CU_ASSERT(qpair.first_fused_req == NULL); 209698bbb72dSTomasz Kulasek 209798bbb72dSTomasz Kulasek /* Write as FUSE_FIRST (Wrong op code) */ 209898bbb72dSTomasz Kulasek cmd.fuse = SPDK_NVME_CMD_FUSE_FIRST; 209998bbb72dSTomasz Kulasek cmd.opc = SPDK_NVME_OPC_WRITE; 210098bbb72dSTomasz Kulasek 210198bbb72dSTomasz Kulasek spdk_nvmf_request_exec(&req); 210298bbb72dSTomasz Kulasek CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_OPCODE); 210398bbb72dSTomasz Kulasek CU_ASSERT(qpair.first_fused_req == NULL); 210498bbb72dSTomasz Kulasek 210598bbb72dSTomasz Kulasek /* Compare as FUSE_SECOND (Wrong op code) */ 210698bbb72dSTomasz Kulasek cmd.fuse = SPDK_NVME_CMD_FUSE_FIRST; 210798bbb72dSTomasz Kulasek cmd.opc = SPDK_NVME_OPC_COMPARE; 210898bbb72dSTomasz Kulasek 210998bbb72dSTomasz Kulasek spdk_nvmf_request_exec(&req); 211098bbb72dSTomasz Kulasek CU_ASSERT(qpair.first_fused_req != NULL); 211198bbb72dSTomasz Kulasek CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 211298bbb72dSTomasz Kulasek 211398bbb72dSTomasz Kulasek cmd.fuse = SPDK_NVME_CMD_FUSE_SECOND; 211498bbb72dSTomasz Kulasek cmd.opc = SPDK_NVME_OPC_COMPARE; 211598bbb72dSTomasz Kulasek 211698bbb72dSTomasz Kulasek spdk_nvmf_request_exec(&req); 211798bbb72dSTomasz Kulasek CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_OPCODE); 211898bbb72dSTomasz Kulasek CU_ASSERT(qpair.first_fused_req == NULL); 2119d37555b4SJonas Pfefferle 2120d37555b4SJonas Pfefferle spdk_bit_array_free(&ctrlr.visible_ns); 212198bbb72dSTomasz Kulasek } 212298bbb72dSTomasz Kulasek 2123d33466d0SJin Yu static void 2124d33466d0SJin Yu test_multi_async_event_reqs(void) 2125d33466d0SJin Yu { 2126d33466d0SJin Yu struct spdk_nvmf_subsystem subsystem = {}; 2127d33466d0SJin Yu struct spdk_nvmf_qpair qpair = {}; 2128d33466d0SJin Yu struct spdk_nvmf_ctrlr ctrlr = {}; 2129d33466d0SJin Yu struct spdk_nvmf_request req[5] = {}; 2130d33466d0SJin Yu struct spdk_nvmf_ns *ns_ptrs[1] = {}; 2131d33466d0SJin Yu struct spdk_nvmf_ns ns = {}; 2132d33466d0SJin Yu union nvmf_h2c_msg cmd[5] = {}; 2133d33466d0SJin Yu union nvmf_c2h_msg rsp[5] = {}; 2134d33466d0SJin Yu 2135d33466d0SJin Yu struct spdk_nvmf_poll_group group = {}; 2136d33466d0SJin Yu struct spdk_nvmf_subsystem_poll_group sgroups = {}; 2137d33466d0SJin Yu 2138d33466d0SJin Yu int i; 2139d33466d0SJin Yu 2140d33466d0SJin Yu ns_ptrs[0] = &ns; 2141d33466d0SJin Yu subsystem.ns = ns_ptrs; 2142d33466d0SJin Yu subsystem.max_nsid = 1; 2143d33466d0SJin Yu subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 2144d33466d0SJin Yu 2145d33466d0SJin Yu ns.opts.nsid = 1; 2146d33466d0SJin Yu group.sgroups = &sgroups; 2147d33466d0SJin Yu 2148d33466d0SJin Yu qpair.ctrlr = &ctrlr; 2149d33466d0SJin Yu qpair.group = &group; 2150315d47daSShuhei Matsumoto TAILQ_INIT(&qpair.outstanding); 2151d33466d0SJin Yu 2152d33466d0SJin Yu ctrlr.subsys = &subsystem; 2153d33466d0SJin Yu ctrlr.vcprop.cc.bits.en = 1; 2154fcc426bdSJacek Kalwas ctrlr.thread = spdk_get_thread(); 2155d33466d0SJin Yu 2156d33466d0SJin Yu for (i = 0; i < 5; i++) { 2157d33466d0SJin Yu cmd[i].nvme_cmd.opc = SPDK_NVME_OPC_ASYNC_EVENT_REQUEST; 21588bbc7b69SPawel Baldysiak cmd[i].nvme_cmd.nsid = 0; 2159d33466d0SJin Yu cmd[i].nvme_cmd.cid = i; 2160d33466d0SJin Yu 2161d33466d0SJin Yu req[i].qpair = &qpair; 2162d33466d0SJin Yu req[i].cmd = &cmd[i]; 2163d33466d0SJin Yu req[i].rsp = &rsp[i]; 2164315d47daSShuhei Matsumoto TAILQ_INSERT_TAIL(&qpair.outstanding, &req[i], link); 2165d33466d0SJin Yu } 2166d33466d0SJin Yu 2167982c25feSChangpeng Liu /* Target can store SPDK_NVMF_MAX_ASYNC_EVENTS reqs */ 2168982c25feSChangpeng Liu sgroups.mgmt_io_outstanding = SPDK_NVMF_MAX_ASYNC_EVENTS; 2169982c25feSChangpeng Liu for (i = 0; i < SPDK_NVMF_MAX_ASYNC_EVENTS; i++) { 2170d33466d0SJin Yu CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req[i]) == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 2171d33466d0SJin Yu CU_ASSERT(ctrlr.nr_aer_reqs == i + 1); 2172d33466d0SJin Yu } 2173312a9d60SBen Walker CU_ASSERT(sgroups.mgmt_io_outstanding == 0); 2174d33466d0SJin Yu 2175982c25feSChangpeng Liu /* Exceeding the SPDK_NVMF_MAX_ASYNC_EVENTS reports error */ 2176d33466d0SJin Yu CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req[4]) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 2177982c25feSChangpeng Liu CU_ASSERT(ctrlr.nr_aer_reqs == SPDK_NVMF_MAX_ASYNC_EVENTS); 217875a12cbfSSlawomir Ptak CU_ASSERT(rsp[4].nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 217975a12cbfSSlawomir Ptak CU_ASSERT(rsp[4].nvme_cpl.status.sc == SPDK_NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED); 2180d33466d0SJin Yu 2181d33466d0SJin Yu /* Test if the aer_reqs keep continuous when abort a req in the middle */ 2182315d47daSShuhei Matsumoto CU_ASSERT(nvmf_qpair_abort_aer(&qpair, 2) == true); 2183d33466d0SJin Yu CU_ASSERT(ctrlr.aer_req[0] == &req[0]); 2184d33466d0SJin Yu CU_ASSERT(ctrlr.aer_req[1] == &req[1]); 2185d33466d0SJin Yu CU_ASSERT(ctrlr.aer_req[2] == &req[3]); 2186d33466d0SJin Yu 2187315d47daSShuhei Matsumoto CU_ASSERT(nvmf_qpair_abort_aer(&qpair, 3) == true); 2188d33466d0SJin Yu CU_ASSERT(ctrlr.aer_req[0] == &req[0]); 2189d33466d0SJin Yu CU_ASSERT(ctrlr.aer_req[1] == &req[1]); 2190d33466d0SJin Yu CU_ASSERT(ctrlr.aer_req[2] == NULL); 2191d33466d0SJin Yu CU_ASSERT(ctrlr.nr_aer_reqs == 2); 2192315d47daSShuhei Matsumoto 2193315d47daSShuhei Matsumoto TAILQ_REMOVE(&qpair.outstanding, &req[0], link); 2194315d47daSShuhei Matsumoto TAILQ_REMOVE(&qpair.outstanding, &req[1], link); 2195d33466d0SJin Yu } 2196d33466d0SJin Yu 219707bfc3cbSShuhei Matsumoto static void 219807bfc3cbSShuhei Matsumoto test_get_ana_log_page_one_ns_per_anagrp(void) 219907bfc3cbSShuhei Matsumoto { 2200568c5c3bSAlex Michon #define UT_ANA_DESC_MAX_SIZE (sizeof(struct spdk_nvme_ana_group_descriptor) + sizeof(uint32_t)) 2201568c5c3bSAlex Michon #define UT_ANA_LOG_PAGE_MAX_SIZE (sizeof(struct spdk_nvme_ana_page) + 3 * UT_ANA_DESC_MAX_SIZE) 2202568c5c3bSAlex Michon #define UT_ANA_DESC_SIZE(rgo) (sizeof(struct spdk_nvme_ana_group_descriptor) + (rgo ? 0 : sizeof(uint32_t))) 2203568c5c3bSAlex Michon #define UT_ANA_LOG_PAGE_SIZE(rgo) (sizeof(struct spdk_nvme_ana_page) + 3 * UT_ANA_DESC_SIZE(rgo)) 220407bfc3cbSShuhei Matsumoto uint32_t ana_group[3]; 220507bfc3cbSShuhei Matsumoto struct spdk_nvmf_subsystem subsystem = { .ana_group = ana_group }; 220674f8f371SMonica Kenguva struct spdk_nvmf_ctrlr ctrlr = {}; 2207785d10b5SShuhei Matsumoto enum spdk_nvme_ana_state ana_state[3]; 2208785d10b5SShuhei Matsumoto struct spdk_nvmf_subsystem_listener listener = { .ana_state = ana_state }; 220974f8f371SMonica Kenguva struct spdk_nvmf_ns ns[3]; 221074f8f371SMonica Kenguva struct spdk_nvmf_ns *ns_arr[3] = {&ns[0], &ns[1], &ns[2]}; 221174f8f371SMonica Kenguva uint64_t offset; 221274f8f371SMonica Kenguva uint32_t length; 221374f8f371SMonica Kenguva int i; 2214568c5c3bSAlex Michon char expected_page[UT_ANA_LOG_PAGE_MAX_SIZE] = {0}; 2215568c5c3bSAlex Michon char actual_page[UT_ANA_LOG_PAGE_MAX_SIZE] = {0}; 2216d07c581bSJiewei Ke struct iovec iov, iovs[2]; 221774f8f371SMonica Kenguva struct spdk_nvme_ana_page *ana_hdr; 2218568c5c3bSAlex Michon char _ana_desc[UT_ANA_DESC_MAX_SIZE]; 221974f8f371SMonica Kenguva struct spdk_nvme_ana_group_descriptor *ana_desc; 2220568c5c3bSAlex Michon uint32_t rgo; 222174f8f371SMonica Kenguva 222274f8f371SMonica Kenguva subsystem.ns = ns_arr; 222374f8f371SMonica Kenguva subsystem.max_nsid = 3; 222407bfc3cbSShuhei Matsumoto for (i = 0; i < 3; i++) { 222507bfc3cbSShuhei Matsumoto subsystem.ana_group[i] = 1; 222607bfc3cbSShuhei Matsumoto } 222774f8f371SMonica Kenguva ctrlr.subsys = &subsystem; 222874f8f371SMonica Kenguva ctrlr.listener = &listener; 2229785d10b5SShuhei Matsumoto 2230785d10b5SShuhei Matsumoto for (i = 0; i < 3; i++) { 2231785d10b5SShuhei Matsumoto listener.ana_state[i] = SPDK_NVME_ANA_OPTIMIZED_STATE; 2232785d10b5SShuhei Matsumoto } 223374f8f371SMonica Kenguva 223474f8f371SMonica Kenguva for (i = 0; i < 3; i++) { 223574f8f371SMonica Kenguva ns_arr[i]->nsid = i + 1; 223607bfc3cbSShuhei Matsumoto ns_arr[i]->anagrpid = i + 1; 223774f8f371SMonica Kenguva } 223874f8f371SMonica Kenguva 2239568c5c3bSAlex Michon for (rgo = 0; rgo <= 1; rgo++) { 2240568c5c3bSAlex Michon memset(expected_page, 0, sizeof(expected_page)); 2241568c5c3bSAlex Michon memset(actual_page, 0, sizeof(actual_page)); 2242568c5c3bSAlex Michon 224374f8f371SMonica Kenguva /* create expected page */ 224474f8f371SMonica Kenguva ana_hdr = (void *)&expected_page[0]; 224574f8f371SMonica Kenguva ana_hdr->num_ana_group_desc = 3; 224674f8f371SMonica Kenguva ana_hdr->change_count = 0; 224774f8f371SMonica Kenguva 224874f8f371SMonica Kenguva /* descriptor may be unaligned. So create data and then copy it to the location. */ 224974f8f371SMonica Kenguva ana_desc = (void *)_ana_desc; 225074f8f371SMonica Kenguva offset = sizeof(struct spdk_nvme_ana_page); 225174f8f371SMonica Kenguva 225274f8f371SMonica Kenguva for (i = 0; i < 3; i++) { 2253568c5c3bSAlex Michon memset(ana_desc, 0, UT_ANA_DESC_MAX_SIZE); 225474f8f371SMonica Kenguva ana_desc->ana_group_id = ns_arr[i]->nsid; 2255568c5c3bSAlex Michon ana_desc->num_of_nsid = rgo ? 0 : 1; 225674f8f371SMonica Kenguva ana_desc->change_count = 0; 2257785d10b5SShuhei Matsumoto ana_desc->ana_state = ctrlr.listener->ana_state[i]; 2258568c5c3bSAlex Michon if (!rgo) { 225974f8f371SMonica Kenguva ana_desc->nsid[0] = ns_arr[i]->nsid; 2260568c5c3bSAlex Michon } 2261568c5c3bSAlex Michon memcpy(&expected_page[offset], ana_desc, UT_ANA_DESC_SIZE(rgo)); 2262568c5c3bSAlex Michon offset += UT_ANA_DESC_SIZE(rgo); 226374f8f371SMonica Kenguva } 226474f8f371SMonica Kenguva 226574f8f371SMonica Kenguva /* read entire actual log page */ 226674f8f371SMonica Kenguva offset = 0; 2267568c5c3bSAlex Michon while (offset < UT_ANA_LOG_PAGE_MAX_SIZE) { 2268568c5c3bSAlex Michon length = spdk_min(16, UT_ANA_LOG_PAGE_MAX_SIZE - offset); 2269d07c581bSJiewei Ke iov.iov_base = &actual_page[offset]; 2270d07c581bSJiewei Ke iov.iov_len = length; 2271568c5c3bSAlex Michon nvmf_get_ana_log_page(&ctrlr, &iov, 1, offset, length, 0, rgo); 227274f8f371SMonica Kenguva offset += length; 227374f8f371SMonica Kenguva } 227474f8f371SMonica Kenguva 227574f8f371SMonica Kenguva /* compare expected page and actual page */ 2276568c5c3bSAlex Michon CU_ASSERT(memcmp(expected_page, actual_page, UT_ANA_LOG_PAGE_MAX_SIZE) == 0); 2277d07c581bSJiewei Ke 2278568c5c3bSAlex Michon memset(&actual_page[0], 0, UT_ANA_LOG_PAGE_MAX_SIZE); 2279d07c581bSJiewei Ke offset = 0; 2280d07c581bSJiewei Ke iovs[0].iov_base = &actual_page[offset]; 2281568c5c3bSAlex Michon iovs[0].iov_len = UT_ANA_LOG_PAGE_MAX_SIZE - UT_ANA_DESC_MAX_SIZE + 4; 2282568c5c3bSAlex Michon offset += UT_ANA_LOG_PAGE_MAX_SIZE - UT_ANA_DESC_MAX_SIZE + 4; 2283d07c581bSJiewei Ke iovs[1].iov_base = &actual_page[offset]; 2284568c5c3bSAlex Michon iovs[1].iov_len = UT_ANA_LOG_PAGE_MAX_SIZE - offset; 2285568c5c3bSAlex Michon nvmf_get_ana_log_page(&ctrlr, &iovs[0], 2, 0, UT_ANA_LOG_PAGE_MAX_SIZE, 0, rgo); 2286d07c581bSJiewei Ke 2287568c5c3bSAlex Michon CU_ASSERT(memcmp(expected_page, actual_page, UT_ANA_LOG_PAGE_MAX_SIZE) == 0); 2288568c5c3bSAlex Michon } 228907bfc3cbSShuhei Matsumoto 229007bfc3cbSShuhei Matsumoto #undef UT_ANA_DESC_SIZE 229107bfc3cbSShuhei Matsumoto #undef UT_ANA_LOG_PAGE_SIZE 2292568c5c3bSAlex Michon #undef UT_ANA_DESC_MAX_SIZE 2293568c5c3bSAlex Michon #undef UT_ANA_LOG_PAGE_MAX_SIZE 229474f8f371SMonica Kenguva } 229574f8f371SMonica Kenguva 22968cd9ef28SJiewei Ke static void 229707bfc3cbSShuhei Matsumoto test_get_ana_log_page_multi_ns_per_anagrp(void) 229807bfc3cbSShuhei Matsumoto { 2299568c5c3bSAlex Michon #define UT_ANA_LOG_PAGE_SIZE(rgo) (sizeof(struct spdk_nvme_ana_page) + \ 2300568c5c3bSAlex Michon sizeof(struct spdk_nvme_ana_group_descriptor) * 2 + \ 2301568c5c3bSAlex Michon (rgo ? 0 : (sizeof(uint32_t) * 5))) 2302568c5c3bSAlex Michon #define UT_ANA_LOG_PAGE_MAX_SIZE (sizeof(struct spdk_nvme_ana_page) + \ 230307bfc3cbSShuhei Matsumoto sizeof(struct spdk_nvme_ana_group_descriptor) * 2 + \ 230407bfc3cbSShuhei Matsumoto sizeof(uint32_t) * 5) 230507bfc3cbSShuhei Matsumoto struct spdk_nvmf_ns ns[5]; 230607bfc3cbSShuhei Matsumoto struct spdk_nvmf_ns *ns_arr[5] = {&ns[0], &ns[1], &ns[2], &ns[3], &ns[4]}; 230707bfc3cbSShuhei Matsumoto uint32_t ana_group[5] = {0}; 230807bfc3cbSShuhei Matsumoto struct spdk_nvmf_subsystem subsystem = { .ns = ns_arr, .ana_group = ana_group, }; 2309785d10b5SShuhei Matsumoto enum spdk_nvme_ana_state ana_state[5]; 2310785d10b5SShuhei Matsumoto struct spdk_nvmf_subsystem_listener listener = { .ana_state = ana_state, }; 231107bfc3cbSShuhei Matsumoto struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsystem, .listener = &listener, }; 2312568c5c3bSAlex Michon char expected_page[UT_ANA_LOG_PAGE_MAX_SIZE] = {0}; 2313568c5c3bSAlex Michon char actual_page[UT_ANA_LOG_PAGE_MAX_SIZE] = {0}; 231407bfc3cbSShuhei Matsumoto struct iovec iov, iovs[2]; 231507bfc3cbSShuhei Matsumoto struct spdk_nvme_ana_page *ana_hdr; 2316568c5c3bSAlex Michon char _ana_desc[UT_ANA_LOG_PAGE_MAX_SIZE]; 231707bfc3cbSShuhei Matsumoto struct spdk_nvme_ana_group_descriptor *ana_desc; 231807bfc3cbSShuhei Matsumoto uint64_t offset; 231907bfc3cbSShuhei Matsumoto uint32_t length; 232007bfc3cbSShuhei Matsumoto int i; 2321568c5c3bSAlex Michon uint32_t rgo; 232207bfc3cbSShuhei Matsumoto 232307bfc3cbSShuhei Matsumoto subsystem.max_nsid = 5; 232407bfc3cbSShuhei Matsumoto subsystem.ana_group[1] = 3; 232507bfc3cbSShuhei Matsumoto subsystem.ana_group[2] = 2; 2326785d10b5SShuhei Matsumoto for (i = 0; i < 5; i++) { 2327785d10b5SShuhei Matsumoto listener.ana_state[i] = SPDK_NVME_ANA_OPTIMIZED_STATE; 2328785d10b5SShuhei Matsumoto } 232907bfc3cbSShuhei Matsumoto 233007bfc3cbSShuhei Matsumoto for (i = 0; i < 5; i++) { 233107bfc3cbSShuhei Matsumoto ns_arr[i]->nsid = i + 1; 233207bfc3cbSShuhei Matsumoto } 233307bfc3cbSShuhei Matsumoto ns_arr[0]->anagrpid = 2; 233407bfc3cbSShuhei Matsumoto ns_arr[1]->anagrpid = 3; 233507bfc3cbSShuhei Matsumoto ns_arr[2]->anagrpid = 2; 233607bfc3cbSShuhei Matsumoto ns_arr[3]->anagrpid = 3; 233707bfc3cbSShuhei Matsumoto ns_arr[4]->anagrpid = 2; 233807bfc3cbSShuhei Matsumoto 2339568c5c3bSAlex Michon for (rgo = 0; rgo <= 1; rgo++) { 2340568c5c3bSAlex Michon memset(expected_page, 0, sizeof(expected_page)); 2341568c5c3bSAlex Michon memset(actual_page, 0, sizeof(actual_page)); 2342568c5c3bSAlex Michon 234307bfc3cbSShuhei Matsumoto /* create expected page */ 234407bfc3cbSShuhei Matsumoto ana_hdr = (void *)&expected_page[0]; 234507bfc3cbSShuhei Matsumoto ana_hdr->num_ana_group_desc = 2; 234607bfc3cbSShuhei Matsumoto ana_hdr->change_count = 0; 234707bfc3cbSShuhei Matsumoto 234807bfc3cbSShuhei Matsumoto /* descriptor may be unaligned. So create data and then copy it to the location. */ 234907bfc3cbSShuhei Matsumoto ana_desc = (void *)_ana_desc; 235007bfc3cbSShuhei Matsumoto offset = sizeof(struct spdk_nvme_ana_page); 235107bfc3cbSShuhei Matsumoto 235207bfc3cbSShuhei Matsumoto memset(_ana_desc, 0, sizeof(_ana_desc)); 235307bfc3cbSShuhei Matsumoto ana_desc->ana_group_id = 2; 2354568c5c3bSAlex Michon ana_desc->num_of_nsid = rgo ? 0 : 3; 235507bfc3cbSShuhei Matsumoto ana_desc->change_count = 0; 235607bfc3cbSShuhei Matsumoto ana_desc->ana_state = SPDK_NVME_ANA_OPTIMIZED_STATE; 2357568c5c3bSAlex Michon if (!rgo) { 235807bfc3cbSShuhei Matsumoto ana_desc->nsid[0] = 1; 235907bfc3cbSShuhei Matsumoto ana_desc->nsid[1] = 3; 236007bfc3cbSShuhei Matsumoto ana_desc->nsid[2] = 5; 2361568c5c3bSAlex Michon } 236207bfc3cbSShuhei Matsumoto memcpy(&expected_page[offset], ana_desc, sizeof(struct spdk_nvme_ana_group_descriptor) + 2363568c5c3bSAlex Michon (rgo ? 0 : (sizeof(uint32_t) * 3))); 2364568c5c3bSAlex Michon offset += sizeof(struct spdk_nvme_ana_group_descriptor) + (rgo ? 0 : (sizeof(uint32_t) * 3)); 236507bfc3cbSShuhei Matsumoto 236607bfc3cbSShuhei Matsumoto memset(_ana_desc, 0, sizeof(_ana_desc)); 236707bfc3cbSShuhei Matsumoto ana_desc->ana_group_id = 3; 2368568c5c3bSAlex Michon ana_desc->num_of_nsid = rgo ? 0 : 2; 236907bfc3cbSShuhei Matsumoto ana_desc->change_count = 0; 237007bfc3cbSShuhei Matsumoto ana_desc->ana_state = SPDK_NVME_ANA_OPTIMIZED_STATE; 2371568c5c3bSAlex Michon if (!rgo) { 237207bfc3cbSShuhei Matsumoto ana_desc->nsid[0] = 2; 237307bfc3cbSShuhei Matsumoto ana_desc->nsid[1] = 4; 2374568c5c3bSAlex Michon } 237507bfc3cbSShuhei Matsumoto memcpy(&expected_page[offset], ana_desc, sizeof(struct spdk_nvme_ana_group_descriptor) + 2376568c5c3bSAlex Michon (rgo ? 0 : (sizeof(uint32_t) * 2))); 237707bfc3cbSShuhei Matsumoto 237807bfc3cbSShuhei Matsumoto /* read entire actual log page, and compare expected page and actual page. */ 237907bfc3cbSShuhei Matsumoto offset = 0; 2380568c5c3bSAlex Michon while (offset < UT_ANA_LOG_PAGE_MAX_SIZE) { 2381568c5c3bSAlex Michon length = spdk_min(16, UT_ANA_LOG_PAGE_MAX_SIZE - offset); 238207bfc3cbSShuhei Matsumoto iov.iov_base = &actual_page[offset]; 238307bfc3cbSShuhei Matsumoto iov.iov_len = length; 2384568c5c3bSAlex Michon nvmf_get_ana_log_page(&ctrlr, &iov, 1, offset, length, 0, rgo); 238507bfc3cbSShuhei Matsumoto offset += length; 238607bfc3cbSShuhei Matsumoto } 238707bfc3cbSShuhei Matsumoto 2388568c5c3bSAlex Michon CU_ASSERT(memcmp(expected_page, actual_page, UT_ANA_LOG_PAGE_MAX_SIZE) == 0); 238907bfc3cbSShuhei Matsumoto 2390568c5c3bSAlex Michon memset(&actual_page[0], 0, UT_ANA_LOG_PAGE_MAX_SIZE); 239107bfc3cbSShuhei Matsumoto offset = 0; 239207bfc3cbSShuhei Matsumoto iovs[0].iov_base = &actual_page[offset]; 2393568c5c3bSAlex Michon iovs[0].iov_len = UT_ANA_LOG_PAGE_MAX_SIZE - sizeof(uint32_t) * 5; 2394568c5c3bSAlex Michon offset += UT_ANA_LOG_PAGE_MAX_SIZE - sizeof(uint32_t) * 5; 239507bfc3cbSShuhei Matsumoto iovs[1].iov_base = &actual_page[offset]; 239607bfc3cbSShuhei Matsumoto iovs[1].iov_len = sizeof(uint32_t) * 5; 2397568c5c3bSAlex Michon nvmf_get_ana_log_page(&ctrlr, &iovs[0], 2, 0, UT_ANA_LOG_PAGE_MAX_SIZE, 0, rgo); 239807bfc3cbSShuhei Matsumoto 2399568c5c3bSAlex Michon CU_ASSERT(memcmp(expected_page, actual_page, UT_ANA_LOG_PAGE_MAX_SIZE) == 0); 2400568c5c3bSAlex Michon } 240107bfc3cbSShuhei Matsumoto 240207bfc3cbSShuhei Matsumoto #undef UT_ANA_LOG_PAGE_SIZE 2403568c5c3bSAlex Michon #undef UT_ANA_LOG_PAGE_MAX_SIZE 240407bfc3cbSShuhei Matsumoto } 240507bfc3cbSShuhei Matsumoto static void 24068cd9ef28SJiewei Ke test_multi_async_events(void) 24078cd9ef28SJiewei Ke { 24088cd9ef28SJiewei Ke struct spdk_nvmf_subsystem subsystem = {}; 24098cd9ef28SJiewei Ke struct spdk_nvmf_qpair qpair = {}; 24108cd9ef28SJiewei Ke struct spdk_nvmf_ctrlr ctrlr = {}; 24118cd9ef28SJiewei Ke struct spdk_nvmf_request req[4] = {}; 24128cd9ef28SJiewei Ke struct spdk_nvmf_ns *ns_ptrs[1] = {}; 24138cd9ef28SJiewei Ke struct spdk_nvmf_ns ns = {}; 24148cd9ef28SJiewei Ke union nvmf_h2c_msg cmd[4] = {}; 24158cd9ef28SJiewei Ke union nvmf_c2h_msg rsp[4] = {}; 24168cd9ef28SJiewei Ke union spdk_nvme_async_event_completion event = {}; 24178cd9ef28SJiewei Ke struct spdk_nvmf_poll_group group = {}; 24188cd9ef28SJiewei Ke struct spdk_nvmf_subsystem_poll_group sgroups = {}; 24198cd9ef28SJiewei Ke int i; 24208cd9ef28SJiewei Ke 24218cd9ef28SJiewei Ke ns_ptrs[0] = &ns; 24228cd9ef28SJiewei Ke subsystem.ns = ns_ptrs; 24238cd9ef28SJiewei Ke subsystem.max_nsid = 1; 24248cd9ef28SJiewei Ke subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 24258cd9ef28SJiewei Ke 24268cd9ef28SJiewei Ke ns.opts.nsid = 1; 24278cd9ef28SJiewei Ke group.sgroups = &sgroups; 24288cd9ef28SJiewei Ke 24298cd9ef28SJiewei Ke qpair.ctrlr = &ctrlr; 24308cd9ef28SJiewei Ke qpair.group = &group; 24318cd9ef28SJiewei Ke TAILQ_INIT(&qpair.outstanding); 24328cd9ef28SJiewei Ke 24338cd9ef28SJiewei Ke ctrlr.subsys = &subsystem; 24348cd9ef28SJiewei Ke ctrlr.vcprop.cc.bits.en = 1; 2435fcc426bdSJacek Kalwas ctrlr.thread = spdk_get_thread(); 24368cd9ef28SJiewei Ke ctrlr.feat.async_event_configuration.bits.ns_attr_notice = 1; 24378cd9ef28SJiewei Ke ctrlr.feat.async_event_configuration.bits.ana_change_notice = 1; 24388cd9ef28SJiewei Ke ctrlr.feat.async_event_configuration.bits.discovery_log_change_notice = 1; 24398cd9ef28SJiewei Ke init_pending_async_events(&ctrlr); 24408cd9ef28SJiewei Ke 24418cd9ef28SJiewei Ke /* Target queue pending events when there is no outstanding AER request */ 24428cd9ef28SJiewei Ke nvmf_ctrlr_async_event_ns_notice(&ctrlr); 24438cd9ef28SJiewei Ke nvmf_ctrlr_async_event_ana_change_notice(&ctrlr); 24448cd9ef28SJiewei Ke nvmf_ctrlr_async_event_discovery_log_change_notice(&ctrlr); 24458cd9ef28SJiewei Ke 24468cd9ef28SJiewei Ke for (i = 0; i < 4; i++) { 24478cd9ef28SJiewei Ke cmd[i].nvme_cmd.opc = SPDK_NVME_OPC_ASYNC_EVENT_REQUEST; 24488bbc7b69SPawel Baldysiak cmd[i].nvme_cmd.nsid = 0; 24498cd9ef28SJiewei Ke cmd[i].nvme_cmd.cid = i; 24508cd9ef28SJiewei Ke 24518cd9ef28SJiewei Ke req[i].qpair = &qpair; 24528cd9ef28SJiewei Ke req[i].cmd = &cmd[i]; 24538cd9ef28SJiewei Ke req[i].rsp = &rsp[i]; 24548cd9ef28SJiewei Ke 24558cd9ef28SJiewei Ke TAILQ_INSERT_TAIL(&qpair.outstanding, &req[i], link); 24568cd9ef28SJiewei Ke 2457312a9d60SBen Walker sgroups.mgmt_io_outstanding = 1; 24588cd9ef28SJiewei Ke if (i < 3) { 24598cd9ef28SJiewei Ke CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req[i]) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 2460312a9d60SBen Walker CU_ASSERT(sgroups.mgmt_io_outstanding == 0); 24618cd9ef28SJiewei Ke CU_ASSERT(ctrlr.nr_aer_reqs == 0); 24628cd9ef28SJiewei Ke } else { 24638cd9ef28SJiewei Ke CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req[i]) == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 2464312a9d60SBen Walker CU_ASSERT(sgroups.mgmt_io_outstanding == 0); 24658cd9ef28SJiewei Ke CU_ASSERT(ctrlr.nr_aer_reqs == 1); 24668cd9ef28SJiewei Ke } 24678cd9ef28SJiewei Ke } 24688cd9ef28SJiewei Ke 24698cd9ef28SJiewei Ke event.raw = rsp[0].nvme_cpl.cdw0; 24708cd9ef28SJiewei Ke CU_ASSERT(event.bits.async_event_info == SPDK_NVME_ASYNC_EVENT_NS_ATTR_CHANGED); 24718cd9ef28SJiewei Ke event.raw = rsp[1].nvme_cpl.cdw0; 24728cd9ef28SJiewei Ke CU_ASSERT(event.bits.async_event_info == SPDK_NVME_ASYNC_EVENT_ANA_CHANGE); 24738cd9ef28SJiewei Ke event.raw = rsp[2].nvme_cpl.cdw0; 24748cd9ef28SJiewei Ke CU_ASSERT(event.bits.async_event_info == SPDK_NVME_ASYNC_EVENT_DISCOVERY_LOG_CHANGE); 24758cd9ef28SJiewei Ke 24768cd9ef28SJiewei Ke cleanup_pending_async_events(&ctrlr); 24778cd9ef28SJiewei Ke } 24788cd9ef28SJiewei Ke 2479a9bdb1eeSJiewei Ke static void 2480a9bdb1eeSJiewei Ke test_rae(void) 2481a9bdb1eeSJiewei Ke { 2482a9bdb1eeSJiewei Ke struct spdk_nvmf_subsystem subsystem = {}; 2483a9bdb1eeSJiewei Ke struct spdk_nvmf_qpair qpair = {}; 2484a9bdb1eeSJiewei Ke struct spdk_nvmf_ctrlr ctrlr = {}; 2485a9bdb1eeSJiewei Ke struct spdk_nvmf_request req[3] = {}; 2486a9bdb1eeSJiewei Ke struct spdk_nvmf_ns *ns_ptrs[1] = {}; 2487a9bdb1eeSJiewei Ke struct spdk_nvmf_ns ns = {}; 2488a9bdb1eeSJiewei Ke union nvmf_h2c_msg cmd[3] = {}; 2489a9bdb1eeSJiewei Ke union nvmf_c2h_msg rsp[3] = {}; 2490a9bdb1eeSJiewei Ke union spdk_nvme_async_event_completion event = {}; 2491a9bdb1eeSJiewei Ke struct spdk_nvmf_poll_group group = {}; 2492a9bdb1eeSJiewei Ke struct spdk_nvmf_subsystem_poll_group sgroups = {}; 2493a9bdb1eeSJiewei Ke int i; 2494a9bdb1eeSJiewei Ke char data[4096]; 2495a9bdb1eeSJiewei Ke 2496a9bdb1eeSJiewei Ke ns_ptrs[0] = &ns; 2497a9bdb1eeSJiewei Ke subsystem.ns = ns_ptrs; 2498a9bdb1eeSJiewei Ke subsystem.max_nsid = 1; 2499a9bdb1eeSJiewei Ke subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 2500a9bdb1eeSJiewei Ke 2501a9bdb1eeSJiewei Ke ns.opts.nsid = 1; 2502a9bdb1eeSJiewei Ke group.sgroups = &sgroups; 2503a9bdb1eeSJiewei Ke 2504a9bdb1eeSJiewei Ke qpair.ctrlr = &ctrlr; 2505a9bdb1eeSJiewei Ke qpair.group = &group; 2506a9bdb1eeSJiewei Ke TAILQ_INIT(&qpair.outstanding); 2507a9bdb1eeSJiewei Ke 2508a9bdb1eeSJiewei Ke ctrlr.subsys = &subsystem; 2509a9bdb1eeSJiewei Ke ctrlr.vcprop.cc.bits.en = 1; 2510fcc426bdSJacek Kalwas ctrlr.thread = spdk_get_thread(); 2511a9bdb1eeSJiewei Ke ctrlr.feat.async_event_configuration.bits.ns_attr_notice = 1; 2512a9bdb1eeSJiewei Ke init_pending_async_events(&ctrlr); 2513a9bdb1eeSJiewei Ke 2514a9bdb1eeSJiewei Ke /* Target queue pending events when there is no outstanding AER request */ 2515a9bdb1eeSJiewei Ke nvmf_ctrlr_async_event_ns_notice(&ctrlr); 2516a9bdb1eeSJiewei Ke nvmf_ctrlr_async_event_ns_notice(&ctrlr); 2517a9bdb1eeSJiewei Ke nvmf_ctrlr_async_event_ns_notice(&ctrlr); 2518a9bdb1eeSJiewei Ke /* only one event will be queued before RAE is clear */ 2519a9bdb1eeSJiewei Ke CU_ASSERT(num_pending_async_events(&ctrlr) == 1); 2520a9bdb1eeSJiewei Ke 2521a9bdb1eeSJiewei Ke req[0].qpair = &qpair; 2522a9bdb1eeSJiewei Ke req[0].cmd = &cmd[0]; 2523a9bdb1eeSJiewei Ke req[0].rsp = &rsp[0]; 2524a9bdb1eeSJiewei Ke cmd[0].nvme_cmd.opc = SPDK_NVME_OPC_ASYNC_EVENT_REQUEST; 25258bbc7b69SPawel Baldysiak cmd[0].nvme_cmd.nsid = 0; 2526a9bdb1eeSJiewei Ke cmd[0].nvme_cmd.cid = 0; 2527a9bdb1eeSJiewei Ke 2528a9bdb1eeSJiewei Ke for (i = 1; i < 3; i++) { 2529a9bdb1eeSJiewei Ke req[i].qpair = &qpair; 2530a9bdb1eeSJiewei Ke req[i].cmd = &cmd[i]; 2531a9bdb1eeSJiewei Ke req[i].rsp = &rsp[i]; 2532a9bdb1eeSJiewei Ke req[i].length = sizeof(data); 2533f029b824SJacek Kalwas SPDK_IOV_ONE(req[i].iov, &req[i].iovcnt, &data, req[i].length); 2534a9bdb1eeSJiewei Ke 2535a9bdb1eeSJiewei Ke cmd[i].nvme_cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE; 2536a9bdb1eeSJiewei Ke cmd[i].nvme_cmd.cdw10_bits.get_log_page.lid = 2537a9bdb1eeSJiewei Ke SPDK_NVME_LOG_CHANGED_NS_LIST; 2538a9bdb1eeSJiewei Ke cmd[i].nvme_cmd.cdw10_bits.get_log_page.numdl = 25391572882aSsunshihao520 spdk_nvme_bytes_to_numd(req[i].length); 2540a9bdb1eeSJiewei Ke cmd[i].nvme_cmd.cid = i; 2541a9bdb1eeSJiewei Ke } 2542a9bdb1eeSJiewei Ke cmd[1].nvme_cmd.cdw10_bits.get_log_page.rae = 1; 2543a9bdb1eeSJiewei Ke cmd[2].nvme_cmd.cdw10_bits.get_log_page.rae = 0; 2544a9bdb1eeSJiewei Ke 2545a9bdb1eeSJiewei Ke /* consume the pending event */ 2546a9bdb1eeSJiewei Ke TAILQ_INSERT_TAIL(&qpair.outstanding, &req[0], link); 2547a9bdb1eeSJiewei Ke CU_ASSERT(nvmf_ctrlr_process_admin_cmd(&req[0]) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 2548a9bdb1eeSJiewei Ke event.raw = rsp[0].nvme_cpl.cdw0; 2549a9bdb1eeSJiewei Ke CU_ASSERT(event.bits.async_event_info == SPDK_NVME_ASYNC_EVENT_NS_ATTR_CHANGED); 2550a9bdb1eeSJiewei Ke CU_ASSERT(num_pending_async_events(&ctrlr) == 0); 2551a9bdb1eeSJiewei Ke 2552a9bdb1eeSJiewei Ke /* get log with RAE set */ 2553a9bdb1eeSJiewei Ke CU_ASSERT(nvmf_ctrlr_get_log_page(&req[1]) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 2554a9bdb1eeSJiewei Ke CU_ASSERT(rsp[1].nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 2555a9bdb1eeSJiewei Ke CU_ASSERT(rsp[1].nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 2556a9bdb1eeSJiewei Ke 2557a9bdb1eeSJiewei Ke /* will not generate new event until RAE is clear */ 2558a9bdb1eeSJiewei Ke nvmf_ctrlr_async_event_ns_notice(&ctrlr); 2559a9bdb1eeSJiewei Ke CU_ASSERT(num_pending_async_events(&ctrlr) == 0); 2560a9bdb1eeSJiewei Ke 2561a9bdb1eeSJiewei Ke /* get log with RAE clear */ 2562a9bdb1eeSJiewei Ke CU_ASSERT(nvmf_ctrlr_get_log_page(&req[2]) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 2563a9bdb1eeSJiewei Ke CU_ASSERT(rsp[2].nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 2564a9bdb1eeSJiewei Ke CU_ASSERT(rsp[2].nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 2565a9bdb1eeSJiewei Ke 2566a9bdb1eeSJiewei Ke nvmf_ctrlr_async_event_ns_notice(&ctrlr); 2567a9bdb1eeSJiewei Ke CU_ASSERT(num_pending_async_events(&ctrlr) == 1); 2568a9bdb1eeSJiewei Ke 2569a9bdb1eeSJiewei Ke cleanup_pending_async_events(&ctrlr); 2570a9bdb1eeSJiewei Ke } 2571a9bdb1eeSJiewei Ke 2572f596245cSMao Jiang static void 2573f596245cSMao Jiang test_nvmf_ctrlr_create_destruct(void) 2574f596245cSMao Jiang { 2575f596245cSMao Jiang struct spdk_nvmf_fabric_connect_data connect_data = {}; 2576f596245cSMao Jiang struct spdk_nvmf_poll_group group = {}; 2577f596245cSMao Jiang struct spdk_nvmf_subsystem_poll_group sgroups[2] = {}; 2578f596245cSMao Jiang struct spdk_nvmf_transport transport = {}; 2579f596245cSMao Jiang struct spdk_nvmf_transport_ops tops = {}; 2580f596245cSMao Jiang struct spdk_nvmf_subsystem subsystem = {}; 2581d37555b4SJonas Pfefferle struct spdk_nvmf_ns *ns_arr[1] = { NULL }; 2582f596245cSMao Jiang struct spdk_nvmf_request req = {}; 2583f596245cSMao Jiang struct spdk_nvmf_qpair qpair = {}; 2584f596245cSMao Jiang struct spdk_nvmf_ctrlr *ctrlr = NULL; 2585f596245cSMao Jiang struct spdk_nvmf_tgt tgt = {}; 2586f596245cSMao Jiang union nvmf_h2c_msg cmd = {}; 2587f596245cSMao Jiang union nvmf_c2h_msg rsp = {}; 2588f596245cSMao Jiang const uint8_t hostid[16] = { 2589f596245cSMao Jiang 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 2590f596245cSMao Jiang 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F 2591f596245cSMao Jiang }; 2592f596245cSMao Jiang const char subnqn[] = "nqn.2016-06.io.spdk:subsystem1"; 2593f596245cSMao Jiang const char hostnqn[] = "nqn.2016-06.io.spdk:host1"; 2594f596245cSMao Jiang 2595f596245cSMao Jiang group.thread = spdk_get_thread(); 2596f596245cSMao Jiang transport.ops = &tops; 2597f596245cSMao Jiang transport.opts.max_aq_depth = 32; 2598f596245cSMao Jiang transport.opts.max_queue_depth = 64; 2599f596245cSMao Jiang transport.opts.max_qpairs_per_ctrlr = 3; 2600f596245cSMao Jiang transport.opts.dif_insert_or_strip = true; 2601f596245cSMao Jiang transport.tgt = &tgt; 2602f596245cSMao Jiang qpair.transport = &transport; 2603f596245cSMao Jiang qpair.group = &group; 2604db221b40SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 2605f596245cSMao Jiang TAILQ_INIT(&qpair.outstanding); 2606f596245cSMao Jiang 2607f596245cSMao Jiang memcpy(connect_data.hostid, hostid, sizeof(hostid)); 2608f596245cSMao Jiang connect_data.cntlid = 0xFFFF; 2609f596245cSMao Jiang snprintf(connect_data.subnqn, sizeof(connect_data.subnqn), "%s", subnqn); 2610f596245cSMao Jiang snprintf(connect_data.hostnqn, sizeof(connect_data.hostnqn), "%s", hostnqn); 2611f596245cSMao Jiang 2612f596245cSMao Jiang subsystem.thread = spdk_get_thread(); 2613f596245cSMao Jiang subsystem.id = 1; 2614f596245cSMao Jiang TAILQ_INIT(&subsystem.ctrlrs); 2615f596245cSMao Jiang subsystem.tgt = &tgt; 2616f596245cSMao Jiang subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 2617f596245cSMao Jiang subsystem.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 2618f596245cSMao Jiang snprintf(subsystem.subnqn, sizeof(subsystem.subnqn), "%s", subnqn); 2619d37555b4SJonas Pfefferle subsystem.ns = ns_arr; 2620f596245cSMao Jiang 2621f596245cSMao Jiang group.sgroups = sgroups; 2622f596245cSMao Jiang 2623f596245cSMao Jiang cmd.connect_cmd.opcode = SPDK_NVME_OPC_FABRIC; 2624f596245cSMao Jiang cmd.connect_cmd.cid = 1; 2625f596245cSMao Jiang cmd.connect_cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_CONNECT; 2626f596245cSMao Jiang cmd.connect_cmd.recfmt = 0; 2627f596245cSMao Jiang cmd.connect_cmd.qid = 0; 2628f596245cSMao Jiang cmd.connect_cmd.sqsize = 31; 2629f596245cSMao Jiang cmd.connect_cmd.cattr = 0; 2630f596245cSMao Jiang cmd.connect_cmd.kato = 120000; 2631f596245cSMao Jiang 2632f596245cSMao Jiang req.qpair = &qpair; 2633f596245cSMao Jiang req.xfer = SPDK_NVME_DATA_HOST_TO_CONTROLLER; 26349fa25237SJohn Levon req.length = sizeof(connect_data); 2635f029b824SJacek Kalwas SPDK_IOV_ONE(req.iov, &req.iovcnt, &connect_data, req.length); 2636f596245cSMao Jiang req.cmd = &cmd; 2637f596245cSMao Jiang req.rsp = &rsp; 2638f596245cSMao Jiang 2639f596245cSMao Jiang TAILQ_INSERT_TAIL(&qpair.outstanding, &req, link); 2640f596245cSMao Jiang sgroups[subsystem.id].mgmt_io_outstanding++; 2641f596245cSMao Jiang 26429fa25237SJohn Levon ctrlr = nvmf_ctrlr_create(&subsystem, &req, &req.cmd->connect_cmd, req.iov[0].iov_base); 2643f596245cSMao Jiang poll_threads(); 2644f596245cSMao Jiang SPDK_CU_ASSERT_FATAL(ctrlr != NULL); 2645f596245cSMao Jiang CU_ASSERT(req.qpair->ctrlr == ctrlr); 2646f596245cSMao Jiang CU_ASSERT(ctrlr->subsys == &subsystem); 2647f596245cSMao Jiang CU_ASSERT(ctrlr->thread == req.qpair->group->thread); 2648f596245cSMao Jiang CU_ASSERT(ctrlr->disconnect_in_progress == false); 2649f596245cSMao Jiang CU_ASSERT(ctrlr->qpair_mask != NULL); 2650f596245cSMao Jiang CU_ASSERT(ctrlr->feat.keep_alive_timer.bits.kato == 120000); 2651f596245cSMao Jiang CU_ASSERT(ctrlr->feat.async_event_configuration.bits.ns_attr_notice == 1); 2652f596245cSMao Jiang CU_ASSERT(ctrlr->feat.volatile_write_cache.bits.wce == 1); 2653f596245cSMao Jiang CU_ASSERT(ctrlr->feat.number_of_queues.bits.ncqr == 1); 2654f596245cSMao Jiang CU_ASSERT(ctrlr->feat.number_of_queues.bits.nsqr == 1); 2655f596245cSMao Jiang CU_ASSERT(!strncmp((void *)&ctrlr->hostid, hostid, 16)); 2656f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.cap.bits.cqr == 1); 2657f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.cap.bits.mqes == 63); 2658f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.cap.bits.ams == 0); 2659f63c0899SChangpeng Liu CU_ASSERT(ctrlr->vcprop.cap.bits.to == NVMF_CTRLR_RESET_SHN_TIMEOUT_IN_MS / 500); 2660f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.cap.bits.dstrd == 0); 2661f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.cap.bits.css == SPDK_NVME_CAP_CSS_NVM); 2662f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.cap.bits.mpsmin == 0); 2663f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.cap.bits.mpsmax == 0); 2664f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.vs.bits.mjr == 1); 2665f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.vs.bits.mnr == 3); 2666f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.vs.bits.ter == 0); 2667f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.cc.raw == 0); 2668f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.cc.bits.en == 0); 2669f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.csts.raw == 0); 2670f596245cSMao Jiang CU_ASSERT(ctrlr->vcprop.csts.bits.rdy == 0); 2671f596245cSMao Jiang CU_ASSERT(ctrlr->dif_insert_or_strip == true); 2672f596245cSMao Jiang 267397385af1SAlexey Marchuk ctrlr->in_destruct = true; 2674f596245cSMao Jiang nvmf_ctrlr_destruct(ctrlr); 2675f596245cSMao Jiang poll_threads(); 2676f596245cSMao Jiang CU_ASSERT(TAILQ_EMPTY(&subsystem.ctrlrs)); 2677f596245cSMao Jiang CU_ASSERT(TAILQ_EMPTY(&qpair.outstanding)); 2678f596245cSMao Jiang } 2679f596245cSMao Jiang 26805818b42fSmatthewb static void 26815818b42fSmatthewb test_nvmf_ctrlr_use_zcopy(void) 26825818b42fSmatthewb { 26835818b42fSmatthewb struct spdk_nvmf_subsystem subsystem = {}; 2684aa1d0398SKonrad Sztyber struct spdk_nvmf_transport transport = {}; 26855818b42fSmatthewb struct spdk_nvmf_request req = {}; 26865818b42fSmatthewb struct spdk_nvmf_qpair qpair = {}; 26875818b42fSmatthewb struct spdk_nvmf_ctrlr ctrlr = {}; 26885818b42fSmatthewb union nvmf_h2c_msg cmd = {}; 26895818b42fSmatthewb struct spdk_nvmf_ns ns = {}; 26905818b42fSmatthewb struct spdk_nvmf_ns *subsys_ns[1] = {}; 26915818b42fSmatthewb struct spdk_bdev bdev = {}; 26925818b42fSmatthewb struct spdk_nvmf_poll_group group = {}; 26935818b42fSmatthewb struct spdk_nvmf_subsystem_poll_group sgroups = {}; 26945818b42fSmatthewb struct spdk_nvmf_subsystem_pg_ns_info ns_info = {}; 26955818b42fSmatthewb struct spdk_io_channel io_ch = {}; 26965818b42fSmatthewb int opc; 26975818b42fSmatthewb 26985818b42fSmatthewb subsystem.subtype = SPDK_NVMF_SUBTYPE_NVME; 26995818b42fSmatthewb ns.bdev = &bdev; 27005818b42fSmatthewb 27015818b42fSmatthewb subsystem.id = 0; 27025818b42fSmatthewb subsystem.max_nsid = 1; 27035818b42fSmatthewb subsys_ns[0] = &ns; 27045818b42fSmatthewb subsystem.ns = (struct spdk_nvmf_ns **)&subsys_ns; 27055818b42fSmatthewb 27065818b42fSmatthewb ctrlr.subsys = &subsystem; 2707d37555b4SJonas Pfefferle ctrlr.visible_ns = spdk_bit_array_create(1); 2708d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 0); 27095818b42fSmatthewb 2710aa1d0398SKonrad Sztyber transport.opts.zcopy = true; 2711aa1d0398SKonrad Sztyber 27125818b42fSmatthewb qpair.ctrlr = &ctrlr; 27135818b42fSmatthewb qpair.group = &group; 27145818b42fSmatthewb qpair.qid = 1; 2715781d42adSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_ENABLED; 2716aa1d0398SKonrad Sztyber qpair.transport = &transport; 27175818b42fSmatthewb 27185818b42fSmatthewb group.thread = spdk_get_thread(); 27195818b42fSmatthewb group.num_sgroups = 1; 27205818b42fSmatthewb sgroups.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 27215818b42fSmatthewb sgroups.num_ns = 1; 27225818b42fSmatthewb ns_info.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 27235818b42fSmatthewb ns_info.channel = &io_ch; 27245818b42fSmatthewb sgroups.ns_info = &ns_info; 27255818b42fSmatthewb TAILQ_INIT(&sgroups.queued); 27265818b42fSmatthewb group.sgroups = &sgroups; 27275818b42fSmatthewb TAILQ_INIT(&qpair.outstanding); 27285818b42fSmatthewb 27295818b42fSmatthewb req.qpair = &qpair; 27305818b42fSmatthewb req.cmd = &cmd; 27316631c2a8SKonrad Sztyber req.zcopy_phase = NVMF_ZCOPY_PHASE_NONE; 27325818b42fSmatthewb 27335818b42fSmatthewb /* Admin queue */ 27345818b42fSmatthewb qpair.qid = 0; 27355818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req) == false); 27365818b42fSmatthewb qpair.qid = 1; 27375818b42fSmatthewb 27385818b42fSmatthewb /* Invalid Opcodes */ 27395818b42fSmatthewb for (opc = 0; opc <= 255; opc++) { 27405818b42fSmatthewb cmd.nvme_cmd.opc = (enum spdk_nvme_nvm_opcode) opc; 27415818b42fSmatthewb if ((cmd.nvme_cmd.opc != SPDK_NVME_OPC_READ) && 27425818b42fSmatthewb (cmd.nvme_cmd.opc != SPDK_NVME_OPC_WRITE)) { 27435818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req) == false); 27445818b42fSmatthewb } 27455818b42fSmatthewb } 27465818b42fSmatthewb cmd.nvme_cmd.opc = SPDK_NVME_OPC_WRITE; 27475818b42fSmatthewb 27485818b42fSmatthewb /* Fused WRITE */ 27495818b42fSmatthewb cmd.nvme_cmd.fuse = SPDK_NVME_CMD_FUSE_SECOND; 27505818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req) == false); 27515818b42fSmatthewb cmd.nvme_cmd.fuse = SPDK_NVME_CMD_FUSE_NONE; 27525818b42fSmatthewb 27535818b42fSmatthewb /* Non bdev */ 27545818b42fSmatthewb cmd.nvme_cmd.nsid = 4; 27555818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req) == false); 27565818b42fSmatthewb cmd.nvme_cmd.nsid = 1; 27575818b42fSmatthewb 27585818b42fSmatthewb /* ZCOPY Not supported */ 27595818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req) == false); 2760aa1d0398SKonrad Sztyber ns.zcopy = true; 2761aa1d0398SKonrad Sztyber 2762aa1d0398SKonrad Sztyber /* ZCOPY disabled on transport level */ 2763aa1d0398SKonrad Sztyber transport.opts.zcopy = false; 2764aa1d0398SKonrad Sztyber CU_ASSERT(nvmf_ctrlr_use_zcopy(&req) == false); 2765aa1d0398SKonrad Sztyber transport.opts.zcopy = true; 27665818b42fSmatthewb 27675818b42fSmatthewb /* Success */ 27685818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req)); 27696631c2a8SKonrad Sztyber CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT); 2770d37555b4SJonas Pfefferle 2771d37555b4SJonas Pfefferle spdk_bit_array_free(&ctrlr.visible_ns); 27725818b42fSmatthewb } 27735818b42fSmatthewb 27745818b42fSmatthewb static void 277592d7df1fSKonrad Sztyber qpair_state_change_done(void *cb_arg, int status) 277692d7df1fSKonrad Sztyber { 277792d7df1fSKonrad Sztyber } 277892d7df1fSKonrad Sztyber 277992d7df1fSKonrad Sztyber static void 27805818b42fSmatthewb test_spdk_nvmf_request_zcopy_start(void) 27815818b42fSmatthewb { 27825818b42fSmatthewb struct spdk_nvmf_request req = {}; 27835818b42fSmatthewb struct spdk_nvmf_qpair qpair = {}; 2784aa1d0398SKonrad Sztyber struct spdk_nvmf_transport transport = {}; 27855818b42fSmatthewb struct spdk_nvme_cmd cmd = {}; 27865818b42fSmatthewb union nvmf_c2h_msg rsp = {}; 27875818b42fSmatthewb struct spdk_nvmf_ctrlr ctrlr = {}; 27885818b42fSmatthewb struct spdk_nvmf_subsystem subsystem = {}; 27895818b42fSmatthewb struct spdk_nvmf_ns ns = {}; 27905818b42fSmatthewb struct spdk_nvmf_ns *subsys_ns[1] = {}; 2791785d10b5SShuhei Matsumoto enum spdk_nvme_ana_state ana_state[1]; 2792785d10b5SShuhei Matsumoto struct spdk_nvmf_subsystem_listener listener = { .ana_state = ana_state }; 27935818b42fSmatthewb struct spdk_bdev bdev = { .blockcnt = 100, .blocklen = 512}; 27945818b42fSmatthewb 27955818b42fSmatthewb struct spdk_nvmf_poll_group group = {}; 27965818b42fSmatthewb struct spdk_nvmf_subsystem_poll_group sgroups = {}; 27975818b42fSmatthewb struct spdk_nvmf_subsystem_pg_ns_info ns_info = {}; 27985818b42fSmatthewb struct spdk_io_channel io_ch = {}; 27995818b42fSmatthewb 28005818b42fSmatthewb ns.bdev = &bdev; 28015818b42fSmatthewb ns.zcopy = true; 280207bfc3cbSShuhei Matsumoto ns.anagrpid = 1; 28035818b42fSmatthewb 28045818b42fSmatthewb subsystem.id = 0; 28055818b42fSmatthewb subsystem.max_nsid = 1; 28065818b42fSmatthewb subsys_ns[0] = &ns; 28075818b42fSmatthewb subsystem.ns = (struct spdk_nvmf_ns **)&subsys_ns; 28085818b42fSmatthewb 2809785d10b5SShuhei Matsumoto listener.ana_state[0] = SPDK_NVME_ANA_OPTIMIZED_STATE; 28105818b42fSmatthewb 28115818b42fSmatthewb /* Enable controller */ 28125818b42fSmatthewb ctrlr.vcprop.cc.bits.en = 1; 28135818b42fSmatthewb ctrlr.subsys = (struct spdk_nvmf_subsystem *)&subsystem; 28145818b42fSmatthewb ctrlr.listener = &listener; 2815d37555b4SJonas Pfefferle ctrlr.visible_ns = spdk_bit_array_create(1); 2816d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 0); 28175818b42fSmatthewb 2818aa1d0398SKonrad Sztyber transport.opts.zcopy = true; 2819aa1d0398SKonrad Sztyber 28205818b42fSmatthewb group.thread = spdk_get_thread(); 28215818b42fSmatthewb group.num_sgroups = 1; 28225818b42fSmatthewb sgroups.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 28235818b42fSmatthewb sgroups.num_ns = 1; 28245818b42fSmatthewb ns_info.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 28255818b42fSmatthewb ns_info.channel = &io_ch; 28265818b42fSmatthewb sgroups.ns_info = &ns_info; 28275818b42fSmatthewb TAILQ_INIT(&sgroups.queued); 28285818b42fSmatthewb group.sgroups = &sgroups; 28295818b42fSmatthewb TAILQ_INIT(&qpair.outstanding); 28305818b42fSmatthewb 28315818b42fSmatthewb qpair.ctrlr = &ctrlr; 28325818b42fSmatthewb qpair.group = &group; 2833aa1d0398SKonrad Sztyber qpair.transport = &transport; 28345818b42fSmatthewb qpair.qid = 1; 2835781d42adSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_ENABLED; 28365818b42fSmatthewb 28375818b42fSmatthewb cmd.nsid = 1; 28385818b42fSmatthewb 28395818b42fSmatthewb req.qpair = &qpair; 28405818b42fSmatthewb req.cmd = (union nvmf_h2c_msg *)&cmd; 28415818b42fSmatthewb req.rsp = &rsp; 28426631c2a8SKonrad Sztyber req.zcopy_phase = NVMF_ZCOPY_PHASE_NONE; 28435818b42fSmatthewb cmd.opc = SPDK_NVME_OPC_READ; 28445818b42fSmatthewb 28455818b42fSmatthewb /* Fail because no controller */ 28465818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req)); 28475818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT); 284833e23361SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 28495818b42fSmatthewb qpair.ctrlr = NULL; 285092d7df1fSKonrad Sztyber spdk_nvmf_request_zcopy_start(&req); 285192d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(req.zcopy_phase, NVMF_ZCOPY_PHASE_INIT_FAILED); 285292d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sct, SPDK_NVME_SCT_GENERIC); 285392d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sc, SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR); 285433e23361SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_ENABLED; 28555818b42fSmatthewb qpair.ctrlr = &ctrlr; 28566631c2a8SKonrad Sztyber req.zcopy_phase = NVMF_ZCOPY_PHASE_NONE; 28575818b42fSmatthewb 28585818b42fSmatthewb /* Fail because bad NSID */ 28595818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req)); 28605818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT); 28615818b42fSmatthewb cmd.nsid = 0; 286292d7df1fSKonrad Sztyber spdk_nvmf_request_zcopy_start(&req); 286392d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(req.zcopy_phase, NVMF_ZCOPY_PHASE_INIT_FAILED); 286492d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sct, SPDK_NVME_SCT_GENERIC); 286592d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sc, SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 28665818b42fSmatthewb cmd.nsid = 1; 28676631c2a8SKonrad Sztyber req.zcopy_phase = NVMF_ZCOPY_PHASE_NONE; 28685818b42fSmatthewb 28695818b42fSmatthewb /* Fail because bad Channel */ 28705818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req)); 28715818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT); 28725818b42fSmatthewb ns_info.channel = NULL; 287392d7df1fSKonrad Sztyber spdk_nvmf_request_zcopy_start(&req); 287492d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(req.zcopy_phase, NVMF_ZCOPY_PHASE_INIT_FAILED); 287592d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sct, SPDK_NVME_SCT_GENERIC); 287692d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sc, SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT); 28775818b42fSmatthewb ns_info.channel = &io_ch; 28786631c2a8SKonrad Sztyber req.zcopy_phase = NVMF_ZCOPY_PHASE_NONE; 28795818b42fSmatthewb 288034edd9f1SKamil Godzwon /* Queue the request because NSID is not active */ 28815818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req)); 28825818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT); 28835818b42fSmatthewb ns_info.state = SPDK_NVMF_SUBSYSTEM_PAUSING; 288492d7df1fSKonrad Sztyber spdk_nvmf_request_zcopy_start(&req); 288592d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(req.zcopy_phase, NVMF_ZCOPY_PHASE_INIT); 288692d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(TAILQ_FIRST(&sgroups.queued), &req); 28875818b42fSmatthewb ns_info.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 288892d7df1fSKonrad Sztyber TAILQ_REMOVE(&sgroups.queued, &req, link); 28896631c2a8SKonrad Sztyber req.zcopy_phase = NVMF_ZCOPY_PHASE_NONE; 28905818b42fSmatthewb 28915818b42fSmatthewb /* Fail because QPair is not active */ 28925818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req)); 28935818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT); 28945818b42fSmatthewb qpair.state = SPDK_NVMF_QPAIR_DEACTIVATING; 289592d7df1fSKonrad Sztyber qpair.state_cb = qpair_state_change_done; 289692d7df1fSKonrad Sztyber spdk_nvmf_request_zcopy_start(&req); 289792d7df1fSKonrad Sztyber CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT_FAILED); 2898781d42adSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_ENABLED; 289992d7df1fSKonrad Sztyber qpair.state_cb = NULL; 29006631c2a8SKonrad Sztyber req.zcopy_phase = NVMF_ZCOPY_PHASE_NONE; 29015818b42fSmatthewb 29020e09df57SKonrad Sztyber /* Fail because nvmf_bdev_ctrlr_zcopy_start fails */ 29035818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req)); 29045818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT); 29055818b42fSmatthewb cmd.cdw10 = bdev.blockcnt; /* SLBA: CDW10 and CDW11 */ 29065818b42fSmatthewb cmd.cdw12 = 100; /* NLB: CDW12 bits 15:00, 0's based */ 29075818b42fSmatthewb req.length = (cmd.cdw12 + 1) * bdev.blocklen; 290892d7df1fSKonrad Sztyber spdk_nvmf_request_zcopy_start(&req); 290992d7df1fSKonrad Sztyber CU_ASSERT_EQUAL(req.zcopy_phase, NVMF_ZCOPY_PHASE_INIT_FAILED); 29105818b42fSmatthewb cmd.cdw10 = 0; 29115818b42fSmatthewb cmd.cdw12 = 0; 29126631c2a8SKonrad Sztyber req.zcopy_phase = NVMF_ZCOPY_PHASE_NONE; 29135818b42fSmatthewb 29145818b42fSmatthewb /* Success */ 29155818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req)); 29165818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT); 291792d7df1fSKonrad Sztyber spdk_nvmf_request_zcopy_start(&req); 29185818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_EXECUTE); 2919d37555b4SJonas Pfefferle 2920d37555b4SJonas Pfefferle spdk_bit_array_free(&ctrlr.visible_ns); 29215818b42fSmatthewb } 29225818b42fSmatthewb 29235818b42fSmatthewb static void 29245818b42fSmatthewb test_zcopy_read(void) 29255818b42fSmatthewb { 29265818b42fSmatthewb struct spdk_nvmf_request req = {}; 29275818b42fSmatthewb struct spdk_nvmf_qpair qpair = {}; 2928aa1d0398SKonrad Sztyber struct spdk_nvmf_transport transport = {}; 29295818b42fSmatthewb struct spdk_nvme_cmd cmd = {}; 29305818b42fSmatthewb union nvmf_c2h_msg rsp = {}; 29315818b42fSmatthewb struct spdk_nvmf_ctrlr ctrlr = {}; 29325818b42fSmatthewb struct spdk_nvmf_subsystem subsystem = {}; 29335818b42fSmatthewb struct spdk_nvmf_ns ns = {}; 29345818b42fSmatthewb struct spdk_nvmf_ns *subsys_ns[1] = {}; 2935785d10b5SShuhei Matsumoto enum spdk_nvme_ana_state ana_state[1]; 2936785d10b5SShuhei Matsumoto struct spdk_nvmf_subsystem_listener listener = { .ana_state = ana_state }; 29375818b42fSmatthewb struct spdk_bdev bdev = { .blockcnt = 100, .blocklen = 512}; 29385818b42fSmatthewb 29395818b42fSmatthewb struct spdk_nvmf_poll_group group = {}; 29405818b42fSmatthewb struct spdk_nvmf_subsystem_poll_group sgroups = {}; 29415818b42fSmatthewb struct spdk_nvmf_subsystem_pg_ns_info ns_info = {}; 29425818b42fSmatthewb struct spdk_io_channel io_ch = {}; 29435818b42fSmatthewb 29445818b42fSmatthewb ns.bdev = &bdev; 29455818b42fSmatthewb ns.zcopy = true; 294607bfc3cbSShuhei Matsumoto ns.anagrpid = 1; 29475818b42fSmatthewb 29485818b42fSmatthewb subsystem.id = 0; 29495818b42fSmatthewb subsystem.max_nsid = 1; 29505818b42fSmatthewb subsys_ns[0] = &ns; 29515818b42fSmatthewb subsystem.ns = (struct spdk_nvmf_ns **)&subsys_ns; 29525818b42fSmatthewb 2953785d10b5SShuhei Matsumoto listener.ana_state[0] = SPDK_NVME_ANA_OPTIMIZED_STATE; 29545818b42fSmatthewb 29555818b42fSmatthewb /* Enable controller */ 29565818b42fSmatthewb ctrlr.vcprop.cc.bits.en = 1; 29575818b42fSmatthewb ctrlr.subsys = (struct spdk_nvmf_subsystem *)&subsystem; 29585818b42fSmatthewb ctrlr.listener = &listener; 2959d37555b4SJonas Pfefferle ctrlr.visible_ns = spdk_bit_array_create(1); 2960d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 0); 29615818b42fSmatthewb 2962aa1d0398SKonrad Sztyber transport.opts.zcopy = true; 2963aa1d0398SKonrad Sztyber 29645818b42fSmatthewb group.thread = spdk_get_thread(); 29655818b42fSmatthewb group.num_sgroups = 1; 29665818b42fSmatthewb sgroups.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 29675818b42fSmatthewb sgroups.num_ns = 1; 29685818b42fSmatthewb ns_info.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 29695818b42fSmatthewb ns_info.channel = &io_ch; 29705818b42fSmatthewb sgroups.ns_info = &ns_info; 29715818b42fSmatthewb TAILQ_INIT(&sgroups.queued); 29725818b42fSmatthewb group.sgroups = &sgroups; 29735818b42fSmatthewb TAILQ_INIT(&qpair.outstanding); 29745818b42fSmatthewb 29755818b42fSmatthewb qpair.ctrlr = &ctrlr; 29765818b42fSmatthewb qpair.group = &group; 2977aa1d0398SKonrad Sztyber qpair.transport = &transport; 29785818b42fSmatthewb qpair.qid = 1; 2979781d42adSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_ENABLED; 29805818b42fSmatthewb 29815818b42fSmatthewb cmd.nsid = 1; 29825818b42fSmatthewb 29835818b42fSmatthewb req.qpair = &qpair; 29845818b42fSmatthewb req.cmd = (union nvmf_h2c_msg *)&cmd; 29855818b42fSmatthewb req.rsp = &rsp; 29865818b42fSmatthewb cmd.opc = SPDK_NVME_OPC_READ; 29875818b42fSmatthewb 29885818b42fSmatthewb /* Prepare for zcopy */ 29895818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req)); 29905818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT); 29915818b42fSmatthewb CU_ASSERT(qpair.outstanding.tqh_first == NULL); 29925818b42fSmatthewb CU_ASSERT(ns_info.io_outstanding == 0); 29935818b42fSmatthewb 29945818b42fSmatthewb /* Perform the zcopy start */ 299592d7df1fSKonrad Sztyber spdk_nvmf_request_zcopy_start(&req); 29965818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_EXECUTE); 29975818b42fSmatthewb CU_ASSERT(req.zcopy_bdev_io == zcopy_start_bdev_io_read); 29985818b42fSmatthewb CU_ASSERT(qpair.outstanding.tqh_first == &req); 29995818b42fSmatthewb CU_ASSERT(ns_info.io_outstanding == 1); 30005818b42fSmatthewb CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 30015818b42fSmatthewb 30025818b42fSmatthewb /* Perform the zcopy end */ 30031d6adfb0SBen Walker spdk_nvmf_request_zcopy_end(&req, false); 30045818b42fSmatthewb CU_ASSERT(req.zcopy_bdev_io == NULL); 30055818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_COMPLETE); 30065818b42fSmatthewb CU_ASSERT(qpair.outstanding.tqh_first == NULL); 30075818b42fSmatthewb CU_ASSERT(ns_info.io_outstanding == 0); 3008f65099d3SKonrad Sztyber CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 3009d37555b4SJonas Pfefferle 3010d37555b4SJonas Pfefferle spdk_bit_array_free(&ctrlr.visible_ns); 30115818b42fSmatthewb } 30125818b42fSmatthewb 30135818b42fSmatthewb static void 30145818b42fSmatthewb test_zcopy_write(void) 30155818b42fSmatthewb { 30165818b42fSmatthewb struct spdk_nvmf_request req = {}; 30175818b42fSmatthewb struct spdk_nvmf_qpair qpair = {}; 3018aa1d0398SKonrad Sztyber struct spdk_nvmf_transport transport = {}; 30195818b42fSmatthewb struct spdk_nvme_cmd cmd = {}; 30205818b42fSmatthewb union nvmf_c2h_msg rsp = {}; 30215818b42fSmatthewb struct spdk_nvmf_ctrlr ctrlr = {}; 30225818b42fSmatthewb struct spdk_nvmf_subsystem subsystem = {}; 30235818b42fSmatthewb struct spdk_nvmf_ns ns = {}; 30245818b42fSmatthewb struct spdk_nvmf_ns *subsys_ns[1] = {}; 3025785d10b5SShuhei Matsumoto enum spdk_nvme_ana_state ana_state[1]; 3026785d10b5SShuhei Matsumoto struct spdk_nvmf_subsystem_listener listener = { .ana_state = ana_state }; 30275818b42fSmatthewb struct spdk_bdev bdev = { .blockcnt = 100, .blocklen = 512}; 30285818b42fSmatthewb 30295818b42fSmatthewb struct spdk_nvmf_poll_group group = {}; 30305818b42fSmatthewb struct spdk_nvmf_subsystem_poll_group sgroups = {}; 30315818b42fSmatthewb struct spdk_nvmf_subsystem_pg_ns_info ns_info = {}; 30325818b42fSmatthewb struct spdk_io_channel io_ch = {}; 30335818b42fSmatthewb 30345818b42fSmatthewb ns.bdev = &bdev; 30355818b42fSmatthewb ns.zcopy = true; 303607bfc3cbSShuhei Matsumoto ns.anagrpid = 1; 30375818b42fSmatthewb 30385818b42fSmatthewb subsystem.id = 0; 30395818b42fSmatthewb subsystem.max_nsid = 1; 30405818b42fSmatthewb subsys_ns[0] = &ns; 30415818b42fSmatthewb subsystem.ns = (struct spdk_nvmf_ns **)&subsys_ns; 30425818b42fSmatthewb 3043785d10b5SShuhei Matsumoto listener.ana_state[0] = SPDK_NVME_ANA_OPTIMIZED_STATE; 30445818b42fSmatthewb 30455818b42fSmatthewb /* Enable controller */ 30465818b42fSmatthewb ctrlr.vcprop.cc.bits.en = 1; 30475818b42fSmatthewb ctrlr.subsys = (struct spdk_nvmf_subsystem *)&subsystem; 30485818b42fSmatthewb ctrlr.listener = &listener; 3049d37555b4SJonas Pfefferle ctrlr.visible_ns = spdk_bit_array_create(1); 3050d37555b4SJonas Pfefferle spdk_bit_array_set(ctrlr.visible_ns, 0); 30515818b42fSmatthewb 3052aa1d0398SKonrad Sztyber transport.opts.zcopy = true; 3053aa1d0398SKonrad Sztyber 30545818b42fSmatthewb group.thread = spdk_get_thread(); 30555818b42fSmatthewb group.num_sgroups = 1; 30565818b42fSmatthewb sgroups.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 30575818b42fSmatthewb sgroups.num_ns = 1; 30585818b42fSmatthewb ns_info.state = SPDK_NVMF_SUBSYSTEM_ACTIVE; 30595818b42fSmatthewb ns_info.channel = &io_ch; 30605818b42fSmatthewb sgroups.ns_info = &ns_info; 30615818b42fSmatthewb TAILQ_INIT(&sgroups.queued); 30625818b42fSmatthewb group.sgroups = &sgroups; 30635818b42fSmatthewb TAILQ_INIT(&qpair.outstanding); 30645818b42fSmatthewb 30655818b42fSmatthewb qpair.ctrlr = &ctrlr; 30665818b42fSmatthewb qpair.group = &group; 3067aa1d0398SKonrad Sztyber qpair.transport = &transport; 30685818b42fSmatthewb qpair.qid = 1; 3069781d42adSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_ENABLED; 30705818b42fSmatthewb 30715818b42fSmatthewb cmd.nsid = 1; 30725818b42fSmatthewb 30735818b42fSmatthewb req.qpair = &qpair; 30745818b42fSmatthewb req.cmd = (union nvmf_h2c_msg *)&cmd; 30755818b42fSmatthewb req.rsp = &rsp; 30765818b42fSmatthewb cmd.opc = SPDK_NVME_OPC_WRITE; 30775818b42fSmatthewb 30785818b42fSmatthewb /* Prepare for zcopy */ 30795818b42fSmatthewb CU_ASSERT(nvmf_ctrlr_use_zcopy(&req)); 30805818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_INIT); 30815818b42fSmatthewb CU_ASSERT(qpair.outstanding.tqh_first == NULL); 30825818b42fSmatthewb CU_ASSERT(ns_info.io_outstanding == 0); 30835818b42fSmatthewb 30845818b42fSmatthewb /* Perform the zcopy start */ 308592d7df1fSKonrad Sztyber spdk_nvmf_request_zcopy_start(&req); 30865818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_EXECUTE); 30875818b42fSmatthewb CU_ASSERT(req.zcopy_bdev_io == zcopy_start_bdev_io_write); 30885818b42fSmatthewb CU_ASSERT(qpair.outstanding.tqh_first == &req); 30895818b42fSmatthewb CU_ASSERT(ns_info.io_outstanding == 1); 30905818b42fSmatthewb CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 30915818b42fSmatthewb 30925818b42fSmatthewb /* Perform the zcopy end */ 30931d6adfb0SBen Walker spdk_nvmf_request_zcopy_end(&req, true); 30945818b42fSmatthewb CU_ASSERT(req.zcopy_bdev_io == NULL); 30955818b42fSmatthewb CU_ASSERT(req.zcopy_phase == NVMF_ZCOPY_PHASE_COMPLETE); 30965818b42fSmatthewb CU_ASSERT(qpair.outstanding.tqh_first == NULL); 30975818b42fSmatthewb CU_ASSERT(ns_info.io_outstanding == 0); 3098f65099d3SKonrad Sztyber CU_ASSERT(nvme_status_success(&rsp.nvme_cpl.status)); 3099d37555b4SJonas Pfefferle 3100d37555b4SJonas Pfefferle spdk_bit_array_free(&ctrlr.visible_ns); 31015818b42fSmatthewb } 31025818b42fSmatthewb 3103d428fbccSMao Jiang static void 3104d428fbccSMao Jiang test_nvmf_property_set(void) 3105d428fbccSMao Jiang { 3106d428fbccSMao Jiang int rc; 3107d428fbccSMao Jiang struct spdk_nvmf_request req = {}; 3108d428fbccSMao Jiang struct spdk_nvmf_qpair qpair = {}; 3109d428fbccSMao Jiang struct spdk_nvmf_ctrlr ctrlr = {}; 3110d428fbccSMao Jiang union nvmf_h2c_msg cmd = {}; 3111d428fbccSMao Jiang union nvmf_c2h_msg rsp = {}; 3112d428fbccSMao Jiang 3113d428fbccSMao Jiang req.qpair = &qpair; 3114d428fbccSMao Jiang qpair.ctrlr = &ctrlr; 3115d428fbccSMao Jiang req.cmd = &cmd; 3116d428fbccSMao Jiang req.rsp = &rsp; 3117d428fbccSMao Jiang 3118d428fbccSMao Jiang /* Invalid parameters */ 3119d428fbccSMao Jiang cmd.prop_set_cmd.attrib.size = SPDK_NVMF_PROP_SIZE_4; 3120d428fbccSMao Jiang cmd.prop_set_cmd.ofst = offsetof(struct spdk_nvme_registers, vs); 3121d428fbccSMao Jiang 3122d428fbccSMao Jiang rc = nvmf_property_set(&req); 3123d428fbccSMao Jiang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3124d428fbccSMao Jiang CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 3125d428fbccSMao Jiang CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 3126d428fbccSMao Jiang 3127d428fbccSMao Jiang cmd.prop_set_cmd.ofst = offsetof(struct spdk_nvme_registers, intms); 3128d428fbccSMao Jiang 3129d428fbccSMao Jiang rc = nvmf_property_get(&req); 3130d428fbccSMao Jiang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3131d428fbccSMao Jiang CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC); 3132d428fbccSMao Jiang CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_PARAM); 3133d428fbccSMao Jiang 3134d428fbccSMao Jiang /* Set cc with same property size */ 3135d428fbccSMao Jiang memset(req.rsp, 0, sizeof(union nvmf_c2h_msg)); 3136d428fbccSMao Jiang cmd.prop_set_cmd.ofst = offsetof(struct spdk_nvme_registers, cc); 3137d428fbccSMao Jiang 3138d428fbccSMao Jiang rc = nvmf_property_set(&req); 3139d428fbccSMao Jiang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3140d428fbccSMao Jiang 3141d428fbccSMao Jiang /* Emulate cc data */ 3142d428fbccSMao Jiang ctrlr.vcprop.cc.raw = 0xDEADBEEF; 3143d428fbccSMao Jiang 3144d428fbccSMao Jiang rc = nvmf_property_get(&req); 3145d428fbccSMao Jiang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3146d428fbccSMao Jiang CU_ASSERT(req.rsp->prop_get_rsp.value.u64 == 0xDEADBEEF); 3147d428fbccSMao Jiang 3148d428fbccSMao Jiang /* Set asq with different property size */ 3149d428fbccSMao Jiang memset(req.rsp, 0, sizeof(union nvmf_c2h_msg)); 3150d428fbccSMao Jiang cmd.prop_set_cmd.attrib.size = SPDK_NVMF_PROP_SIZE_4; 3151d428fbccSMao Jiang cmd.prop_set_cmd.ofst = offsetof(struct spdk_nvme_registers, asq); 3152d428fbccSMao Jiang 3153d428fbccSMao Jiang rc = nvmf_property_set(&req); 3154d428fbccSMao Jiang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3155d428fbccSMao Jiang 3156d428fbccSMao Jiang /* Emulate asq data */ 3157d428fbccSMao Jiang ctrlr.vcprop.asq = 0xAADDADBEEF; 3158d428fbccSMao Jiang 3159d428fbccSMao Jiang rc = nvmf_property_get(&req); 3160d428fbccSMao Jiang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3161d428fbccSMao Jiang CU_ASSERT(req.rsp->prop_get_rsp.value.u64 == 0xDDADBEEF); 3162d428fbccSMao Jiang } 3163d428fbccSMao Jiang 3164acfd87caSxiaoxiangxzhang static void 3165acfd87caSxiaoxiangxzhang test_nvmf_ctrlr_get_features_host_behavior_support(void) 3166acfd87caSxiaoxiangxzhang { 3167acfd87caSxiaoxiangxzhang int rc; 3168acfd87caSxiaoxiangxzhang struct spdk_nvmf_request req = {}; 3169acfd87caSxiaoxiangxzhang struct spdk_nvmf_qpair qpair = {}; 3170acfd87caSxiaoxiangxzhang struct spdk_nvmf_ctrlr ctrlr = {}; 3171acfd87caSxiaoxiangxzhang struct spdk_nvme_host_behavior behavior = {}; 3172acfd87caSxiaoxiangxzhang union nvmf_h2c_msg cmd = {}; 3173acfd87caSxiaoxiangxzhang union nvmf_c2h_msg rsp = {}; 3174acfd87caSxiaoxiangxzhang 3175acfd87caSxiaoxiangxzhang qpair.ctrlr = &ctrlr; 3176acfd87caSxiaoxiangxzhang req.qpair = &qpair; 3177acfd87caSxiaoxiangxzhang req.cmd = &cmd; 3178acfd87caSxiaoxiangxzhang req.rsp = &rsp; 3179acfd87caSxiaoxiangxzhang 3180acfd87caSxiaoxiangxzhang /* Invalid data */ 31819fa25237SJohn Levon req.length = sizeof(struct spdk_nvme_host_behavior); 3182ad521730SJohn Levon req.iovcnt = 0; 3183acfd87caSxiaoxiangxzhang 3184acfd87caSxiaoxiangxzhang rc = nvmf_ctrlr_get_features_host_behavior_support(&req); 3185acfd87caSxiaoxiangxzhang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3186acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 3187acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 3188acfd87caSxiaoxiangxzhang 3189acfd87caSxiaoxiangxzhang /* Wrong structure length */ 3190acfd87caSxiaoxiangxzhang req.length = sizeof(struct spdk_nvme_host_behavior) - 1; 3191f029b824SJacek Kalwas SPDK_IOV_ONE(req.iov, &req.iovcnt, &behavior, req.length); 3192acfd87caSxiaoxiangxzhang 3193acfd87caSxiaoxiangxzhang rc = nvmf_ctrlr_get_features_host_behavior_support(&req); 3194acfd87caSxiaoxiangxzhang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3195acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 3196acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 3197acfd87caSxiaoxiangxzhang 3198acfd87caSxiaoxiangxzhang /* Get Features Host Behavior Support Success */ 3199acfd87caSxiaoxiangxzhang req.length = sizeof(struct spdk_nvme_host_behavior); 3200f029b824SJacek Kalwas SPDK_IOV_ONE(req.iov, &req.iovcnt, &behavior, req.length); 3201ad521730SJohn Levon 3202acfd87caSxiaoxiangxzhang ctrlr.acre_enabled = true; 32031e2d5e50SShuhei Matsumoto ctrlr.lbafee_enabled = true; 32049fa25237SJohn Levon behavior.acre = false; 32051e2d5e50SShuhei Matsumoto behavior.lbafee = false; 3206acfd87caSxiaoxiangxzhang 3207acfd87caSxiaoxiangxzhang rc = nvmf_ctrlr_get_features_host_behavior_support(&req); 3208acfd87caSxiaoxiangxzhang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 32099fa25237SJohn Levon CU_ASSERT(behavior.acre == true); 32101e2d5e50SShuhei Matsumoto CU_ASSERT(behavior.lbafee == true); 3211acfd87caSxiaoxiangxzhang } 3212acfd87caSxiaoxiangxzhang 3213acfd87caSxiaoxiangxzhang static void 3214acfd87caSxiaoxiangxzhang test_nvmf_ctrlr_set_features_host_behavior_support(void) 3215acfd87caSxiaoxiangxzhang { 3216acfd87caSxiaoxiangxzhang int rc; 3217acfd87caSxiaoxiangxzhang struct spdk_nvmf_request req = {}; 3218acfd87caSxiaoxiangxzhang struct spdk_nvmf_qpair qpair = {}; 3219acfd87caSxiaoxiangxzhang struct spdk_nvmf_ctrlr ctrlr = {}; 3220acfd87caSxiaoxiangxzhang struct spdk_nvme_host_behavior host_behavior = {}; 3221acfd87caSxiaoxiangxzhang union nvmf_h2c_msg cmd = {}; 3222acfd87caSxiaoxiangxzhang union nvmf_c2h_msg rsp = {}; 3223acfd87caSxiaoxiangxzhang 3224acfd87caSxiaoxiangxzhang qpair.ctrlr = &ctrlr; 3225acfd87caSxiaoxiangxzhang req.qpair = &qpair; 3226acfd87caSxiaoxiangxzhang req.cmd = &cmd; 3227acfd87caSxiaoxiangxzhang req.rsp = &rsp; 3228acfd87caSxiaoxiangxzhang req.iov[0].iov_base = &host_behavior; 3229acfd87caSxiaoxiangxzhang req.iov[0].iov_len = sizeof(host_behavior); 3230acfd87caSxiaoxiangxzhang 3231acfd87caSxiaoxiangxzhang /* Invalid iovcnt */ 3232acfd87caSxiaoxiangxzhang req.iovcnt = 0; 3233acfd87caSxiaoxiangxzhang rc = SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; 3234acfd87caSxiaoxiangxzhang req.rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 3235acfd87caSxiaoxiangxzhang req.rsp->nvme_cpl.status.sc = SPDK_NVME_SC_SUCCESS; 3236acfd87caSxiaoxiangxzhang 3237acfd87caSxiaoxiangxzhang rc = nvmf_ctrlr_set_features_host_behavior_support(&req); 3238acfd87caSxiaoxiangxzhang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3239acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 3240acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 3241acfd87caSxiaoxiangxzhang 3242acfd87caSxiaoxiangxzhang /* Invalid iov_len */ 3243acfd87caSxiaoxiangxzhang req.iovcnt = 1; 3244acfd87caSxiaoxiangxzhang req.iov[0].iov_len = 0; 3245acfd87caSxiaoxiangxzhang rc = SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; 3246acfd87caSxiaoxiangxzhang req.rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 3247acfd87caSxiaoxiangxzhang req.rsp->nvme_cpl.status.sc = SPDK_NVME_SC_SUCCESS; 3248acfd87caSxiaoxiangxzhang 3249acfd87caSxiaoxiangxzhang rc = nvmf_ctrlr_set_features_host_behavior_support(&req); 3250acfd87caSxiaoxiangxzhang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3251acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 3252acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 3253acfd87caSxiaoxiangxzhang 32541e2d5e50SShuhei Matsumoto /* acre is false but lbafee is true */ 3255acfd87caSxiaoxiangxzhang host_behavior.acre = 0; 32561e2d5e50SShuhei Matsumoto host_behavior.lbafee = 1; 3257acfd87caSxiaoxiangxzhang req.iov[0].iov_len = sizeof(struct spdk_nvme_host_behavior); 3258acfd87caSxiaoxiangxzhang rc = SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; 3259acfd87caSxiaoxiangxzhang req.rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 3260acfd87caSxiaoxiangxzhang req.rsp->nvme_cpl.status.sc = SPDK_NVME_SC_SUCCESS; 3261acfd87caSxiaoxiangxzhang 3262acfd87caSxiaoxiangxzhang rc = nvmf_ctrlr_set_features_host_behavior_support(&req); 3263acfd87caSxiaoxiangxzhang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3264acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 3265acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 3266acfd87caSxiaoxiangxzhang CU_ASSERT(ctrlr.acre_enabled == false); 32671e2d5e50SShuhei Matsumoto CU_ASSERT(ctrlr.lbafee_enabled == true); 3268acfd87caSxiaoxiangxzhang 32691e2d5e50SShuhei Matsumoto /* acre is true but lbafee is false */ 3270acfd87caSxiaoxiangxzhang host_behavior.acre = 1; 32711e2d5e50SShuhei Matsumoto host_behavior.lbafee = 0; 3272acfd87caSxiaoxiangxzhang req.iov[0].iov_len = sizeof(struct spdk_nvme_host_behavior); 3273acfd87caSxiaoxiangxzhang rc = SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; 3274acfd87caSxiaoxiangxzhang req.rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 3275acfd87caSxiaoxiangxzhang req.rsp->nvme_cpl.status.sc = SPDK_NVME_SC_SUCCESS; 3276acfd87caSxiaoxiangxzhang 3277acfd87caSxiaoxiangxzhang rc = nvmf_ctrlr_set_features_host_behavior_support(&req); 3278acfd87caSxiaoxiangxzhang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3279acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 3280acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS); 3281acfd87caSxiaoxiangxzhang CU_ASSERT(ctrlr.acre_enabled == true); 32821e2d5e50SShuhei Matsumoto CU_ASSERT(ctrlr.lbafee_enabled == false); 3283acfd87caSxiaoxiangxzhang 3284acfd87caSxiaoxiangxzhang /* Invalid acre */ 3285acfd87caSxiaoxiangxzhang host_behavior.acre = 2; 3286acfd87caSxiaoxiangxzhang rc = SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; 3287acfd87caSxiaoxiangxzhang req.rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 3288acfd87caSxiaoxiangxzhang req.rsp->nvme_cpl.status.sc = SPDK_NVME_SC_SUCCESS; 3289acfd87caSxiaoxiangxzhang 3290acfd87caSxiaoxiangxzhang rc = nvmf_ctrlr_set_features_host_behavior_support(&req); 3291acfd87caSxiaoxiangxzhang CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 3292acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 3293acfd87caSxiaoxiangxzhang CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 32941e2d5e50SShuhei Matsumoto 32951e2d5e50SShuhei Matsumoto /* Invalid lbafee */ 32961e2d5e50SShuhei Matsumoto host_behavior.lbafee = 3; 32971e2d5e50SShuhei Matsumoto rc = SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; 32981e2d5e50SShuhei Matsumoto req.rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 32991e2d5e50SShuhei Matsumoto req.rsp->nvme_cpl.status.sc = SPDK_NVME_SC_SUCCESS; 33001e2d5e50SShuhei Matsumoto 33011e2d5e50SShuhei Matsumoto rc = nvmf_ctrlr_set_features_host_behavior_support(&req); 33021e2d5e50SShuhei Matsumoto CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE); 33031e2d5e50SShuhei Matsumoto CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 33041e2d5e50SShuhei Matsumoto CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD); 3305acfd87caSxiaoxiangxzhang } 3306acfd87caSxiaoxiangxzhang 3307d37555b4SJonas Pfefferle static void 3308d37555b4SJonas Pfefferle test_nvmf_ctrlr_ns_attachment(void) 3309d37555b4SJonas Pfefferle { 3310d37555b4SJonas Pfefferle struct spdk_nvmf_subsystem subsystem = {}; 3311d37555b4SJonas Pfefferle struct spdk_nvmf_ns ns1 = { 3312d37555b4SJonas Pfefferle .nsid = 1, 3313d37555b4SJonas Pfefferle .always_visible = false 3314d37555b4SJonas Pfefferle }; 3315d37555b4SJonas Pfefferle struct spdk_nvmf_ns ns3 = { 3316d37555b4SJonas Pfefferle .nsid = 3, 3317d37555b4SJonas Pfefferle .always_visible = false 3318d37555b4SJonas Pfefferle }; 3319d37555b4SJonas Pfefferle struct spdk_nvmf_ctrlr ctrlrA = { 3320d37555b4SJonas Pfefferle .subsys = &subsystem 3321d37555b4SJonas Pfefferle }; 3322d37555b4SJonas Pfefferle struct spdk_nvmf_ctrlr ctrlrB = { 3323d37555b4SJonas Pfefferle .subsys = &subsystem 3324d37555b4SJonas Pfefferle }; 3325d37555b4SJonas Pfefferle struct spdk_nvmf_host *host; 3326d37555b4SJonas Pfefferle uint32_t nsid; 3327d37555b4SJonas Pfefferle 3328d37555b4SJonas Pfefferle subsystem.max_nsid = 3; 3329d37555b4SJonas Pfefferle subsystem.ns = calloc(subsystem.max_nsid, sizeof(subsystem.ns)); 3330d37555b4SJonas Pfefferle SPDK_CU_ASSERT_FATAL(subsystem.ns != NULL); 3331d37555b4SJonas Pfefferle 3332d37555b4SJonas Pfefferle /* nsid = 2 -> unallocated, nsid = 1,3 -> allocated */ 3333d37555b4SJonas Pfefferle subsystem.ns[0] = &ns1; 3334d37555b4SJonas Pfefferle subsystem.ns[2] = &ns3; 3335d37555b4SJonas Pfefferle 3336d37555b4SJonas Pfefferle snprintf(ctrlrA.hostnqn, sizeof(ctrlrA.hostnqn), "nqn.2016-06.io.spdk:host1"); 3337d37555b4SJonas Pfefferle ctrlrA.visible_ns = spdk_bit_array_create(subsystem.max_nsid); 3338d37555b4SJonas Pfefferle SPDK_CU_ASSERT_FATAL(ctrlrA.visible_ns != NULL); 3339d37555b4SJonas Pfefferle snprintf(ctrlrB.hostnqn, sizeof(ctrlrB.hostnqn), "nqn.2016-06.io.spdk:host2"); 3340d37555b4SJonas Pfefferle ctrlrB.visible_ns = spdk_bit_array_create(subsystem.max_nsid); 3341d37555b4SJonas Pfefferle SPDK_CU_ASSERT_FATAL(ctrlrB.visible_ns != NULL); 3342d37555b4SJonas Pfefferle 3343d37555b4SJonas Pfefferle /* Do not auto attach and no cold attach of any ctrlr */ 3344d37555b4SJonas Pfefferle nsid = 1; 3345d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == NULL); 3346d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns3, ctrlrA.hostnqn) == NULL); 3347d37555b4SJonas Pfefferle nvmf_ctrlr_init_visible_ns(&ctrlrA); 3348d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 3349d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 3350d37555b4SJonas Pfefferle nsid = 3; 3351d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 3352d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 3353d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == NULL); 3354d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns3, ctrlrA.hostnqn) == NULL); 3355d37555b4SJonas Pfefferle 3356d37555b4SJonas Pfefferle /* Cold attach ctrlrA to namespace 1 */ 3357d37555b4SJonas Pfefferle nsid = 1; 3358d37555b4SJonas Pfefferle host = calloc(1, sizeof(*host)); 3359d37555b4SJonas Pfefferle SPDK_CU_ASSERT_FATAL(host != NULL); 3360d37555b4SJonas Pfefferle snprintf(host->nqn, sizeof(host->nqn), "%s", ctrlrA.hostnqn); 3361d37555b4SJonas Pfefferle TAILQ_INSERT_HEAD(&ns1.hosts, host, link); 3362d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == host); 3363d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns3, ctrlrA.hostnqn) == NULL); 3364d37555b4SJonas Pfefferle nvmf_ctrlr_init_visible_ns(&ctrlrA); 3365d37555b4SJonas Pfefferle CU_ASSERT(spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 3366d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 3367d37555b4SJonas Pfefferle nsid = 3; 3368d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 3369d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 3370d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == host); 3371d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns3, ctrlrA.hostnqn) == NULL); 3372d37555b4SJonas Pfefferle 3373d37555b4SJonas Pfefferle /* Detach ctrlrA from namespace 1 */ 3374d37555b4SJonas Pfefferle nsid = 1; 3375d37555b4SJonas Pfefferle spdk_bit_array_clear(ctrlrA.visible_ns, nsid - 1); 3376d37555b4SJonas Pfefferle TAILQ_REMOVE(&ns1.hosts, host, link); 3377d37555b4SJonas Pfefferle free(host); 3378d37555b4SJonas Pfefferle 3379d37555b4SJonas Pfefferle /* Auto attach any ctrlr to namespace 2 */ 3380d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == NULL); 3381d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns3, ctrlrA.hostnqn) == NULL); 3382d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 3383d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 3384d37555b4SJonas Pfefferle nsid = 3; 3385d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 3386d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 3387d37555b4SJonas Pfefferle ns1.always_visible = true; 3388d37555b4SJonas Pfefferle nvmf_ctrlr_init_visible_ns(&ctrlrA); 3389d37555b4SJonas Pfefferle nsid = 1; 3390d37555b4SJonas Pfefferle CU_ASSERT(spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 3391d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 3392d37555b4SJonas Pfefferle nsid = 3; 3393d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 3394d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 3395d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == NULL); 3396d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns3, ctrlrA.hostnqn) == NULL); 3397d37555b4SJonas Pfefferle nvmf_ctrlr_init_visible_ns(&ctrlrB); 3398d37555b4SJonas Pfefferle nsid = 1; 3399d37555b4SJonas Pfefferle CU_ASSERT(spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 3400d37555b4SJonas Pfefferle CU_ASSERT(spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 3401d37555b4SJonas Pfefferle nsid = 3; 3402d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrA.visible_ns, nsid - 1)); 3403d37555b4SJonas Pfefferle CU_ASSERT(!spdk_bit_array_get(ctrlrB.visible_ns, nsid - 1)); 3404d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns1, ctrlrA.hostnqn) == NULL); 3405d37555b4SJonas Pfefferle CU_ASSERT(nvmf_ns_find_host(&ns3, ctrlrA.hostnqn) == NULL); 3406d37555b4SJonas Pfefferle 3407d37555b4SJonas Pfefferle free(ctrlrA.visible_ns); 3408d37555b4SJonas Pfefferle free(ctrlrB.visible_ns); 3409d37555b4SJonas Pfefferle free(subsystem.ns); 3410d37555b4SJonas Pfefferle } 3411d37555b4SJonas Pfefferle 341233e23361SKonrad Sztyber static void 341333e23361SKonrad Sztyber test_nvmf_check_qpair_active(void) 341433e23361SKonrad Sztyber { 341533e23361SKonrad Sztyber union nvmf_c2h_msg rsp = {}; 341633e23361SKonrad Sztyber union nvmf_h2c_msg cmd = {}; 341733e23361SKonrad Sztyber struct spdk_nvmf_qpair qpair = { .outstanding = TAILQ_HEAD_INITIALIZER(qpair.outstanding) }; 341833e23361SKonrad Sztyber struct spdk_nvmf_request req = { .qpair = &qpair, .cmd = &cmd, .rsp = &rsp }; 341933e23361SKonrad Sztyber size_t i; 342033e23361SKonrad Sztyber 342133e23361SKonrad Sztyber /* qpair is active */ 342233e23361SKonrad Sztyber cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 342333e23361SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_ENABLED; 342433e23361SKonrad Sztyber CU_ASSERT_EQUAL(nvmf_check_qpair_active(&req), true); 342533e23361SKonrad Sztyber 342633e23361SKonrad Sztyber /* qpair is connecting - CONNECT is allowed */ 342733e23361SKonrad Sztyber cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_FABRIC; 342833e23361SKonrad Sztyber cmd.nvmf_cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_CONNECT; 342933e23361SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 343033e23361SKonrad Sztyber CU_ASSERT_EQUAL(nvmf_check_qpair_active(&req), true); 343133e23361SKonrad Sztyber 343233e23361SKonrad Sztyber /* qpair is connecting - other commands are disallowed */ 343333e23361SKonrad Sztyber cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 343433e23361SKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_CONNECTING; 343533e23361SKonrad Sztyber CU_ASSERT_EQUAL(nvmf_check_qpair_active(&req), false); 343633e23361SKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sct, SPDK_NVME_SCT_GENERIC); 343733e23361SKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sc, SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR); 343833e23361SKonrad Sztyber 34390a6bb8caSKonrad Sztyber /* qpair is authenticating - AUTHENTICATION_SEND is allowed */ 34400a6bb8caSKonrad Sztyber cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_FABRIC; 34410a6bb8caSKonrad Sztyber cmd.nvmf_cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND; 34420a6bb8caSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING; 34430a6bb8caSKonrad Sztyber CU_ASSERT_EQUAL(nvmf_check_qpair_active(&req), true); 34440a6bb8caSKonrad Sztyber 34450a6bb8caSKonrad Sztyber /* qpair is authenticating - AUTHENTICATION_RECV is allowed */ 34460a6bb8caSKonrad Sztyber cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_FABRIC; 34470a6bb8caSKonrad Sztyber cmd.nvmf_cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV; 34480a6bb8caSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING; 34490a6bb8caSKonrad Sztyber CU_ASSERT_EQUAL(nvmf_check_qpair_active(&req), true); 34500a6bb8caSKonrad Sztyber 34510a6bb8caSKonrad Sztyber /* qpair is authenticating - other commands are disallowed */ 34520a6bb8caSKonrad Sztyber cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 34530a6bb8caSKonrad Sztyber qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING; 34540a6bb8caSKonrad Sztyber CU_ASSERT_EQUAL(nvmf_check_qpair_active(&req), false); 34550a6bb8caSKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sct, SPDK_NVME_SCT_COMMAND_SPECIFIC); 34560a6bb8caSKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sc, SPDK_NVMF_FABRIC_SC_AUTH_REQUIRED); 34570a6bb8caSKonrad Sztyber 345833e23361SKonrad Sztyber /* qpair is in one of the other states - all commands are disallowed */ 345933e23361SKonrad Sztyber int disallowed_states[] = { 346033e23361SKonrad Sztyber SPDK_NVMF_QPAIR_UNINITIALIZED, 346133e23361SKonrad Sztyber SPDK_NVMF_QPAIR_DEACTIVATING, 346233e23361SKonrad Sztyber SPDK_NVMF_QPAIR_ERROR, 346333e23361SKonrad Sztyber }; 346433e23361SKonrad Sztyber qpair.state_cb = qpair_state_change_done; 346533e23361SKonrad Sztyber cmd.nvme_cmd.opc = SPDK_NVME_OPC_READ; 346633e23361SKonrad Sztyber for (i = 0; i < SPDK_COUNTOF(disallowed_states); ++i) { 346733e23361SKonrad Sztyber qpair.state = disallowed_states[i]; 346833e23361SKonrad Sztyber CU_ASSERT_EQUAL(nvmf_check_qpair_active(&req), false); 346933e23361SKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sct, SPDK_NVME_SCT_GENERIC); 347033e23361SKonrad Sztyber CU_ASSERT_EQUAL(rsp.nvme_cpl.status.sc, SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR); 347133e23361SKonrad Sztyber } 347233e23361SKonrad Sztyber } 347333e23361SKonrad Sztyber 34748dd1cd21SBen Walker int 34758dd1cd21SBen Walker main(int argc, char **argv) 347603788f93SBen Walker { 347703788f93SBen Walker CU_pSuite suite = NULL; 347803788f93SBen Walker unsigned int num_failures; 347903788f93SBen Walker 348078b696bcSVitaliy Mysak CU_initialize_registry(); 348103788f93SBen Walker 348203788f93SBen Walker suite = CU_add_suite("nvmf", NULL, NULL); 3483dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_get_log_page); 3484dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_process_fabrics_cmd); 3485dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_connect); 3486dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_get_ns_id_desc_list); 3487dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_identify_ns); 3488a36785dfSDennis Maisenbacher CU_ADD_TEST(suite, test_identify_ns_iocs_specific); 3489dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_reservation_write_exclusive); 3490dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_reservation_exclusive_access); 3491dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_reservation_write_exclusive_regs_only_and_all_regs); 3492dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_reservation_exclusive_access_regs_only_and_all_regs); 3493dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_reservation_notification_log_page); 3494dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_get_dif_ctx); 3495dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_set_get_features); 3496dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_identify_ctrlr); 3497a36785dfSDennis Maisenbacher CU_ADD_TEST(suite, test_identify_ctrlr_iocs_specific); 3498dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_custom_admin_cmd); 3499dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_fused_compare_and_write); 3500d33466d0SJin Yu CU_ADD_TEST(suite, test_multi_async_event_reqs); 350107bfc3cbSShuhei Matsumoto CU_ADD_TEST(suite, test_get_ana_log_page_one_ns_per_anagrp); 350207bfc3cbSShuhei Matsumoto CU_ADD_TEST(suite, test_get_ana_log_page_multi_ns_per_anagrp); 35038cd9ef28SJiewei Ke CU_ADD_TEST(suite, test_multi_async_events); 3504a9bdb1eeSJiewei Ke CU_ADD_TEST(suite, test_rae); 3505f596245cSMao Jiang CU_ADD_TEST(suite, test_nvmf_ctrlr_create_destruct); 35065818b42fSmatthewb CU_ADD_TEST(suite, test_nvmf_ctrlr_use_zcopy); 35075818b42fSmatthewb CU_ADD_TEST(suite, test_spdk_nvmf_request_zcopy_start); 35085818b42fSmatthewb CU_ADD_TEST(suite, test_zcopy_read); 35095818b42fSmatthewb CU_ADD_TEST(suite, test_zcopy_write); 3510d428fbccSMao Jiang CU_ADD_TEST(suite, test_nvmf_property_set); 3511acfd87caSxiaoxiangxzhang CU_ADD_TEST(suite, test_nvmf_ctrlr_get_features_host_behavior_support); 3512acfd87caSxiaoxiangxzhang CU_ADD_TEST(suite, test_nvmf_ctrlr_set_features_host_behavior_support); 3513d37555b4SJonas Pfefferle CU_ADD_TEST(suite, test_nvmf_ctrlr_ns_attachment); 351433e23361SKonrad Sztyber CU_ADD_TEST(suite, test_nvmf_check_qpair_active); 351503788f93SBen Walker 351606a0d9abSBen Walker allocate_threads(1); 351706a0d9abSBen Walker set_thread(0); 3518f6f1161fSBen Walker 3519ea941caeSKonrad Sztyber num_failures = spdk_ut_run_tests(argc, argv, NULL); 352003788f93SBen Walker CU_cleanup_registry(); 3521f6f1161fSBen Walker 352206a0d9abSBen Walker free_threads(); 3523f6f1161fSBen Walker 352403788f93SBen Walker return num_failures; 352503788f93SBen Walker } 3526