2022-06-03 19:15:11 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
2022-11-01 20:26:26 +00:00
|
|
|
* Copyright (C) 2021 Intel Corporation. All rights reserved.
|
2021-09-23 14:06:55 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "spdk/stdinc.h"
|
|
|
|
#include "spdk_cunit.h"
|
|
|
|
#include "spdk/log.h"
|
2021-10-27 13:00:46 +00:00
|
|
|
#include "spdk/util.h"
|
2021-09-23 14:06:55 +00:00
|
|
|
#include "spdk/nvme.h"
|
2021-11-02 13:17:54 +00:00
|
|
|
#include "spdk/string.h"
|
2021-09-23 14:06:55 +00:00
|
|
|
|
|
|
|
static struct spdk_nvme_transport_id g_trid;
|
|
|
|
static const char *g_trid_str;
|
|
|
|
|
|
|
|
struct status {
|
|
|
|
bool done;
|
|
|
|
struct spdk_nvme_cpl cpl;
|
|
|
|
};
|
|
|
|
|
2021-09-29 12:12:13 +00:00
|
|
|
static inline uint64_t
|
|
|
|
nvme_vtophys(struct spdk_nvme_transport_id *trid, const void *buf, uint64_t *size)
|
|
|
|
{
|
|
|
|
/* vfio-user address translation with IOVA=VA mode */
|
|
|
|
if (trid->trtype != SPDK_NVME_TRANSPORT_VFIOUSER) {
|
|
|
|
return spdk_vtophys(buf, size);
|
|
|
|
} else {
|
|
|
|
return (uint64_t)(uintptr_t)buf;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-23 14:06:55 +00:00
|
|
|
static void
|
|
|
|
wait_for_admin_completion(struct status *s, struct spdk_nvme_ctrlr *ctrlr)
|
|
|
|
{
|
|
|
|
/* Timeout if command does not complete within 1 second. */
|
|
|
|
uint64_t timeout = spdk_get_ticks() + spdk_get_ticks_hz();
|
|
|
|
|
|
|
|
while (!s->done && spdk_get_ticks() < timeout) {
|
|
|
|
spdk_nvme_ctrlr_process_admin_completions(ctrlr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!s->done) {
|
|
|
|
CU_ASSERT(false && "completion timeout");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-29 10:48:10 +00:00
|
|
|
static void
|
|
|
|
wait_for_io_completion(struct status *s, struct spdk_nvme_qpair *qpair)
|
|
|
|
{
|
|
|
|
/* Timeout if command does not complete within 1 second. */
|
|
|
|
uint64_t timeout = spdk_get_ticks() + spdk_get_ticks_hz();
|
|
|
|
|
|
|
|
while (!s->done && spdk_get_ticks() < timeout) {
|
|
|
|
spdk_nvme_qpair_process_completions(qpair, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!s->done) {
|
|
|
|
CU_ASSERT(false && "completion timeout");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-23 14:06:55 +00:00
|
|
|
static void
|
|
|
|
test_cb(void *ctx, const struct spdk_nvme_cpl *cpl)
|
|
|
|
{
|
|
|
|
struct status *s = ctx;
|
|
|
|
|
|
|
|
s->done = true;
|
|
|
|
s->cpl = *cpl;
|
|
|
|
}
|
|
|
|
|
2021-09-29 19:41:41 +00:00
|
|
|
/* Test that target correctly handles various IDENTIFY CNS=1 requests. */
|
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_identify_ctrlr_verify_dptr(void)
|
2021-09-29 19:41:41 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct spdk_nvme_ctrlr_data *ctrlr_data;
|
|
|
|
struct status s;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
/* Allocate data buffer with 4KiB alignment, since we need to test some
|
|
|
|
* very specific PRP cases.
|
|
|
|
*/
|
|
|
|
ctrlr_data = spdk_dma_zmalloc(sizeof(*ctrlr_data), 4096, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr_data != NULL);
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_IDENTIFY;
|
|
|
|
cmd.cdw10_bits.identify.cns = SPDK_NVME_IDENTIFY_CTRLR;
|
|
|
|
|
|
|
|
/* Test a properly formed IDENTIFY CNS=1 request. */
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, ctrlr_data,
|
|
|
|
sizeof(*ctrlr_data), test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Confirm the target fails an IDENTIFY CNS=1 request with incorrect
|
|
|
|
* DPTR lengths.
|
|
|
|
*/
|
|
|
|
s.done = false;
|
|
|
|
|
|
|
|
/* Only specify 1KiB of data, and make sure it specifies a PRP offset
|
|
|
|
* that's 1KiB before the end of the buffer previously allocated.
|
|
|
|
*
|
|
|
|
* The controller needs to recognize that a full 4KiB of data was not
|
|
|
|
* specified in the PRPs, and should fail the command.
|
|
|
|
*/
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd,
|
|
|
|
((uint8_t *)ctrlr_data) + (4096 - 1024),
|
|
|
|
1024, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
spdk_dma_free(ctrlr_data);
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-09-29 20:24:23 +00:00
|
|
|
/* Test that target correctly fails admin commands with fuse != 0 */
|
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_identify_ctrlr_verify_fused(void)
|
2021-09-29 20:24:23 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct spdk_nvme_ctrlr_data *ctrlr_data;
|
|
|
|
struct status s, s2;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
ctrlr_data = spdk_dma_zmalloc(sizeof(*ctrlr_data), 0, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr_data != NULL);
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
/* The nvme driver waits until it sees both fused commands before submitting
|
|
|
|
* both to the queue - so construct two commands here and then check the
|
|
|
|
* both are completed with error status.
|
|
|
|
*/
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_IDENTIFY;
|
|
|
|
cmd.fuse = 0x1;
|
|
|
|
cmd.cdw10_bits.identify.cns = SPDK_NVME_IDENTIFY_CTRLR;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, ctrlr_data,
|
|
|
|
sizeof(*ctrlr_data), test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
cmd.fuse = 0x2;
|
|
|
|
s2.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, ctrlr_data,
|
|
|
|
sizeof(*ctrlr_data), test_cb, &s2);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
wait_for_admin_completion(&s2, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
CU_ASSERT(spdk_nvme_cpl_is_error(&s2.cpl));
|
|
|
|
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
spdk_free(ctrlr_data);
|
|
|
|
}
|
|
|
|
|
2021-09-23 14:06:55 +00:00
|
|
|
/* Test that target correctly handles requests to delete admin SQ/CQ (QID = 0).
|
|
|
|
* Associated with issue #2172.
|
|
|
|
*/
|
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_delete_io_sq_use_admin_qid(void)
|
2021-09-23 14:06:55 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct status s;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
/* Try deleting SQ for QID 0 (admin queue). This is invalid. */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 0; /* admin queue */
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
|
2021-09-29 10:48:10 +00:00
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER);
|
2021-09-23 14:06:55 +00:00
|
|
|
|
2021-11-09 14:47:30 +00:00
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
admin_delete_io_cq_use_admin_qid(void)
|
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct status s;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
2021-09-23 14:06:55 +00:00
|
|
|
/* Try deleting CQ for QID 0 (admin queue). This is invalid. */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_CQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 0; /* admin queue */
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
|
2021-09-29 10:48:10 +00:00
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER);
|
|
|
|
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_delete_io_sq_delete_sq_twice(void)
|
2021-09-29 10:48:10 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_io_qpair_opts opts;
|
|
|
|
struct spdk_nvme_qpair *qpair;
|
|
|
|
struct spdk_nvme_ns *ns;
|
|
|
|
uint32_t nsid;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct status s;
|
|
|
|
void *buf;
|
|
|
|
uint32_t nlbas;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
spdk_nvme_ctrlr_get_default_io_qpair_opts(ctrlr, &opts, sizeof(opts));
|
|
|
|
qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, &opts, sizeof(opts));
|
|
|
|
SPDK_CU_ASSERT_FATAL(qpair);
|
|
|
|
|
|
|
|
nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr);
|
|
|
|
ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ns != NULL);
|
|
|
|
|
|
|
|
/* READ command should execute successfully. */
|
|
|
|
nlbas = 1;
|
|
|
|
buf = spdk_dma_zmalloc(nlbas * spdk_nvme_ns_get_sector_size(ns), 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ns_cmd_read_with_md(ns, qpair, buf, NULL, 0, nlbas, test_cb, &s, 0, 0, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(rc == 0);
|
|
|
|
|
|
|
|
wait_for_io_completion(&s, qpair);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Delete SQ 1, this is valid. */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 1;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Try deleting SQ 1 again, this is invalid. */
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER);
|
2021-09-23 14:06:55 +00:00
|
|
|
|
2021-12-02 14:58:44 +00:00
|
|
|
/* Delete CQ 1, this is valid. */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_CQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 1;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
2021-09-29 10:48:10 +00:00
|
|
|
spdk_dma_free(buf);
|
2021-09-23 14:06:55 +00:00
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-09-29 12:12:13 +00:00
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_create_io_sq_verify_qsize_cqid(void)
|
2021-09-29 12:12:13 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_io_qpair_opts opts;
|
|
|
|
struct spdk_nvme_qpair *qpair;
|
|
|
|
union spdk_nvme_cap_register cap;
|
|
|
|
struct spdk_nvme_ns *ns;
|
|
|
|
uint32_t nsid, mqes;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct status s;
|
|
|
|
void *buf;
|
|
|
|
uint32_t nlbas;
|
|
|
|
uint64_t dma_addr;
|
2021-11-09 13:12:38 +00:00
|
|
|
uint32_t ncqr;
|
2021-09-29 12:12:13 +00:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
spdk_nvme_ctrlr_get_default_io_qpair_opts(ctrlr, &opts, sizeof(opts));
|
|
|
|
qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, &opts, sizeof(opts));
|
|
|
|
SPDK_CU_ASSERT_FATAL(qpair);
|
|
|
|
|
|
|
|
nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr);
|
|
|
|
ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ns != NULL);
|
|
|
|
|
|
|
|
/* READ command should execute successfully. */
|
|
|
|
nlbas = 1;
|
|
|
|
buf = spdk_dma_zmalloc(nlbas * spdk_nvme_ns_get_sector_size(ns), 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ns_cmd_read_with_md(ns, qpair, buf, NULL, 0, nlbas, test_cb, &s, 0, 0, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(rc == 0);
|
|
|
|
|
|
|
|
wait_for_io_completion(&s, qpair);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
spdk_dma_free(buf);
|
|
|
|
|
2021-11-09 13:12:38 +00:00
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_GET_FEATURES;
|
|
|
|
/* Get Maximum Number of CQs */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_NUMBER_OF_QUEUES;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
ncqr = ((s.cpl.cdw0 & 0xffff0000u) >> 16) + 1;
|
|
|
|
|
2021-09-29 12:12:13 +00:00
|
|
|
/* Delete SQ 1, this is valid. */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 1;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
cap = spdk_nvme_ctrlr_get_regs_cap(ctrlr);
|
|
|
|
mqes = cap.bits.mqes + 1;
|
|
|
|
buf = spdk_dma_zmalloc(mqes * sizeof(cmd), 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
|
|
|
|
|
|
|
/* Create SQ 1 again, qsize is 0, this is invalid. */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_CREATE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.create_io_q.qid = 1;
|
|
|
|
cmd.cdw10_bits.create_io_q.qsize = 0; /* 0 based value */
|
|
|
|
cmd.cdw11_bits.create_io_sq.pc = 1;
|
|
|
|
cmd.cdw11_bits.create_io_sq.cqid = 1;
|
|
|
|
dma_addr = nvme_vtophys(&g_trid, buf, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(dma_addr != SPDK_VTOPHYS_ERROR);
|
|
|
|
cmd.dptr.prp.prp1 = dma_addr;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_SIZE);
|
|
|
|
|
|
|
|
/* Create SQ 1 again, qsize is MQES + 1, this is invalid. */
|
|
|
|
cmd.cdw10_bits.create_io_q.qsize = (uint16_t)mqes; /* 0 based value */
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_SIZE);
|
|
|
|
|
2021-11-09 13:12:38 +00:00
|
|
|
/* Create SQ 1 again, CQID is 0, this is invalid. */
|
|
|
|
cmd.cdw10_bits.create_io_q.qsize = cap.bits.mqes; /* 0 based value, valid */
|
|
|
|
cmd.cdw11_bits.create_io_sq.cqid = 0;
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER);
|
|
|
|
|
|
|
|
/* Create SQ 1 again, CQID is NCQR + 1, this is invalid. */
|
|
|
|
cmd.cdw11_bits.create_io_sq.cqid = ncqr + 1;
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER);
|
|
|
|
|
|
|
|
/* Create SQ 1 again, CQID is 1, this is valid. */
|
2021-09-29 12:12:13 +00:00
|
|
|
s.done = false;
|
2021-11-09 13:12:38 +00:00
|
|
|
cmd.cdw11_bits.create_io_sq.cqid = 1;
|
2021-09-29 12:12:13 +00:00
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
spdk_dma_free(buf);
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-11-09 15:57:31 +00:00
|
|
|
static void
|
|
|
|
admin_create_io_sq_verify_pc(void)
|
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
union spdk_nvme_cap_register cap;
|
|
|
|
struct spdk_nvme_io_qpair_opts opts;
|
|
|
|
struct spdk_nvme_qpair *qpair;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct status s;
|
|
|
|
void *buf;
|
|
|
|
uint64_t dma_addr;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
cap = spdk_nvme_ctrlr_get_regs_cap(ctrlr);
|
|
|
|
/* exit the rest of test case if CAP.CQR is 0 */
|
|
|
|
if (!cap.bits.cqr) {
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
spdk_nvme_ctrlr_get_default_io_qpair_opts(ctrlr, &opts, sizeof(opts));
|
|
|
|
qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, &opts, sizeof(opts));
|
|
|
|
SPDK_CU_ASSERT_FATAL(qpair);
|
|
|
|
|
|
|
|
/* Delete SQ 1 first, this is valid. */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 1;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
buf = spdk_dma_zmalloc((cap.bits.mqes + 1) * sizeof(cmd), 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
|
|
|
|
|
|
|
/* Create SQ 1, PC is 0, this is invalid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_CREATE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.create_io_q.qid = 1;
|
|
|
|
cmd.cdw10_bits.create_io_q.qsize = cap.bits.mqes;
|
|
|
|
cmd.cdw11_bits.create_io_sq.pc = 0;
|
|
|
|
cmd.cdw11_bits.create_io_sq.cqid = 1;
|
|
|
|
dma_addr = nvme_vtophys(&g_trid, buf, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(dma_addr != SPDK_VTOPHYS_ERROR);
|
|
|
|
cmd.dptr.prp.prp1 = dma_addr;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD);
|
|
|
|
|
|
|
|
/* Create SQ 1 again, PC is 1, this is valid. */
|
|
|
|
s.done = false;
|
|
|
|
cmd.cdw11_bits.create_io_sq.pc = 1;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
spdk_dma_free(buf);
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-09-29 15:42:43 +00:00
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_delete_io_cq_delete_cq_first(void)
|
2021-09-29 15:42:43 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_io_qpair_opts opts;
|
|
|
|
struct spdk_nvme_qpair *qpair;
|
|
|
|
struct spdk_nvme_ns *ns;
|
|
|
|
uint32_t nsid;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct status s;
|
|
|
|
void *buf;
|
|
|
|
uint32_t nlbas;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
spdk_nvme_ctrlr_get_default_io_qpair_opts(ctrlr, &opts, sizeof(opts));
|
|
|
|
qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, &opts, sizeof(opts));
|
|
|
|
SPDK_CU_ASSERT_FATAL(qpair);
|
|
|
|
|
|
|
|
nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr);
|
|
|
|
ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ns != NULL);
|
|
|
|
|
|
|
|
/* READ command should execute successfully. */
|
|
|
|
nlbas = 1;
|
|
|
|
buf = spdk_dma_zmalloc(nlbas * spdk_nvme_ns_get_sector_size(ns), 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ns_cmd_read_with_md(ns, qpair, buf, NULL, 0, nlbas, test_cb, &s, 0, 0, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(rc == 0);
|
|
|
|
|
|
|
|
wait_for_io_completion(&s, qpair);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Delete CQ 1, this is invalid. */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_CQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 1;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_DELETION);
|
|
|
|
|
|
|
|
/* Delete SQ 1, this is valid. */
|
|
|
|
s.done = false;
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 1;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Delete CQ 1 again, this is valid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_CQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 1;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
spdk_dma_free(buf);
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-11-02 16:03:19 +00:00
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_create_io_cq_verify_iv_pc(void)
|
2021-11-02 16:03:19 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
union spdk_nvme_cap_register cap;
|
|
|
|
uint32_t mqes;
|
|
|
|
uint64_t dma_addr;
|
|
|
|
struct status s;
|
|
|
|
void *buf;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
cap = spdk_nvme_ctrlr_get_regs_cap(ctrlr);
|
|
|
|
mqes = cap.bits.mqes + 1;
|
|
|
|
buf = spdk_dma_zmalloc(mqes * sizeof(struct spdk_nvme_cpl), 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
|
|
|
dma_addr = nvme_vtophys(&g_trid, buf, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(dma_addr != SPDK_VTOPHYS_ERROR);
|
|
|
|
|
|
|
|
/* Create CQ 1, IV is 2048, this is invalid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_CREATE_IO_CQ;
|
|
|
|
cmd.cdw10_bits.create_io_q.qid = 1;
|
|
|
|
cmd.cdw10_bits.create_io_q.qsize = mqes - 1; /* 0 based value */
|
|
|
|
cmd.cdw11_bits.create_io_cq.pc = 1;
|
|
|
|
cmd.cdw11_bits.create_io_cq.ien = 1;
|
|
|
|
cmd.cdw11_bits.create_io_cq.iv = 2048;
|
|
|
|
cmd.dptr.prp.prp1 = dma_addr;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_INTERRUPT_VECTOR);
|
|
|
|
|
|
|
|
/* exit the rest of test case if CAP.CQR is 0 */
|
|
|
|
if (!cap.bits.cqr) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create CQ 1, PC is 0, this is invalid */
|
|
|
|
cmd.cdw11_bits.create_io_cq.pc = 0;
|
|
|
|
cmd.cdw11_bits.create_io_cq.iv = 1;
|
|
|
|
cmd.dptr.prp.prp1 = dma_addr;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD);
|
|
|
|
|
|
|
|
/* PC is 1, this is valid */
|
|
|
|
cmd.cdw11_bits.create_io_cq.pc = 1;
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Delete CQ 1, this is valid. */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_CQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 1;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
out:
|
|
|
|
spdk_dma_free(buf);
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-10-26 22:08:52 +00:00
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
fabric_property_get(void)
|
2021-10-26 22:08:52 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvmf_fabric_prop_set_cmd cmd;
|
|
|
|
struct status s;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opcode = SPDK_NVME_OPC_FABRIC;
|
|
|
|
cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_PROPERTY_GET;
|
|
|
|
cmd.ofst = 0; /* CAP */
|
|
|
|
cmd.attrib.size = SPDK_NVMF_PROP_SIZE_8;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, (struct spdk_nvme_cmd *)&cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
/* Non-fabrics controllers should fail an SPDK_NVME_OPC_FABRIC. */
|
|
|
|
if (spdk_nvme_ctrlr_is_fabrics(ctrlr)) {
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_OPCODE);
|
|
|
|
}
|
|
|
|
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-09-23 14:06:55 +00:00
|
|
|
static int
|
|
|
|
parse_args(int argc, char **argv, struct spdk_env_opts *opts)
|
|
|
|
{
|
2021-10-13 07:12:32 +00:00
|
|
|
int op;
|
2021-09-23 14:06:55 +00:00
|
|
|
|
2021-09-29 10:50:55 +00:00
|
|
|
while ((op = getopt(argc, argv, "gr:")) != -1) {
|
2021-09-23 14:06:55 +00:00
|
|
|
switch (op) {
|
2021-09-29 10:50:55 +00:00
|
|
|
case 'g':
|
|
|
|
opts->hugepage_single_segments = true;
|
|
|
|
break;
|
2021-09-23 14:06:55 +00:00
|
|
|
case 'r':
|
|
|
|
g_trid_str = optarg;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SPDK_ERRLOG("Unknown op '%c'\n", op);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-13 15:36:08 +00:00
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_set_features_number_of_queues(void)
|
2021-10-13 15:36:08 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_io_qpair_opts opts;
|
|
|
|
struct spdk_nvme_qpair *qpair;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct status s;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
/* NCQR and NSQR are 65535, invalid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_SET_FEATURES;
|
|
|
|
cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_NUMBER_OF_QUEUES;
|
|
|
|
cmd.cdw11_bits.feat_num_of_queues.bits.ncqr = UINT16_MAX;
|
|
|
|
cmd.cdw11_bits.feat_num_of_queues.bits.nsqr = UINT16_MAX;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD);
|
|
|
|
|
|
|
|
spdk_nvme_ctrlr_get_default_io_qpair_opts(ctrlr, &opts, sizeof(opts));
|
|
|
|
qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, &opts, sizeof(opts));
|
|
|
|
SPDK_CU_ASSERT_FATAL(qpair);
|
|
|
|
|
|
|
|
/* After the IO queue is created, invalid */
|
|
|
|
cmd.cdw11_bits.feat_num_of_queues.bits.ncqr = 128;
|
|
|
|
cmd.cdw11_bits.feat_num_of_queues.bits.nsqr = 128;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR);
|
|
|
|
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-10-11 14:49:14 +00:00
|
|
|
/* Test the mandatory features with Get Features command:
|
|
|
|
* 01h Arbitration.
|
|
|
|
* 02h Power Management.
|
|
|
|
* 04h Temperature Threshold.
|
|
|
|
* 05h Error Recovery.
|
|
|
|
* 07h Number of Queues.
|
|
|
|
* 08h Interrupt Coalescing.
|
|
|
|
* 09h Interrupt Vector Configuration.
|
|
|
|
* 0Ah Write Atomicity Normal.
|
|
|
|
* 0Bh Asynchronous Event Configuration.
|
|
|
|
* 0Fh Keep Alive Timer.
|
|
|
|
* 16h Host Behavior Support.
|
|
|
|
*/
|
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_get_features_mandatory_features(void)
|
2021-10-11 14:49:14 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct status s;
|
|
|
|
void *buf;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
/* Arbitration */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_GET_FEATURES;
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_ARBITRATION;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Power Management */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_POWER_MANAGEMENT;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Temperature Threshold */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Error Recovery */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_ERROR_RECOVERY;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Number of Queues */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_NUMBER_OF_QUEUES;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Interrupt Coalescing */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_INTERRUPT_COALESCING;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Interrupt Vector Configuration */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Write Atomicity Normal */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_WRITE_ATOMICITY;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Asynchronous Event Configuration */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Keep Alive Timer */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_KEEP_ALIVE_TIMER;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
/* Host Behavior Support */
|
|
|
|
buf = spdk_dma_zmalloc(sizeof(struct spdk_nvme_host_behavior), 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
|
|
|
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_HOST_BEHAVIOR_SUPPORT;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, buf, sizeof(struct spdk_nvme_host_behavior),
|
|
|
|
test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_SUCCESS);
|
|
|
|
|
|
|
|
spdk_dma_free(buf);
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-10-27 13:00:46 +00:00
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_create_io_qp_max_qps(void)
|
2021-10-27 13:00:46 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
struct spdk_nvme_io_qpair_opts opts;
|
|
|
|
struct spdk_nvme_qpair *qpair;
|
|
|
|
struct status s;
|
|
|
|
uint32_t ncqr, nsqr, i, num_of_queues;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_GET_FEATURES;
|
|
|
|
/* Number of Queues */
|
|
|
|
cmd.cdw10_bits.get_features.fid = SPDK_NVME_FEAT_NUMBER_OF_QUEUES;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
nsqr = s.cpl.cdw0 & 0xffffu;
|
|
|
|
ncqr = (s.cpl.cdw0 & 0xffff0000u) >> 16;
|
|
|
|
|
|
|
|
num_of_queues = spdk_min(nsqr, ncqr) + 1;
|
|
|
|
|
|
|
|
spdk_nvme_ctrlr_get_default_io_qpair_opts(ctrlr, &opts, sizeof(opts));
|
|
|
|
/* choose a small value to save memory */
|
|
|
|
opts.io_queue_size = 2;
|
|
|
|
|
|
|
|
/* create all the IO queue pairs, valid */
|
|
|
|
for (i = 0; i < num_of_queues; i++) {
|
|
|
|
qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, &opts, sizeof(opts));
|
|
|
|
CU_ASSERT(qpair != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create one more, invalid */
|
|
|
|
qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, &opts, sizeof(opts));
|
|
|
|
CU_ASSERT(qpair == NULL);
|
|
|
|
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-11-02 13:17:54 +00:00
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_identify_ns(void)
|
2021-11-02 13:17:54 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
const struct spdk_nvme_ctrlr_data *cdata;
|
|
|
|
struct spdk_nvme_ns_data *ns_data;
|
2021-11-04 14:52:45 +00:00
|
|
|
struct spdk_nvme_ns *ns;
|
2021-11-02 13:17:54 +00:00
|
|
|
uint32_t i, active_nsid, inactive_nsid;
|
2021-11-04 14:52:45 +00:00
|
|
|
uint32_t nows, npwg, max_xfer_size;
|
2021-11-02 13:17:54 +00:00
|
|
|
struct status s;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
cdata = spdk_nvme_ctrlr_get_data(ctrlr);
|
|
|
|
/* Find active NSID and inactive NSID if exist */
|
|
|
|
active_nsid = inactive_nsid = 0;
|
|
|
|
for (i = 1; i <= cdata->nn; i++) {
|
|
|
|
if (spdk_nvme_ctrlr_is_active_ns(ctrlr, i)) {
|
|
|
|
active_nsid = i;
|
|
|
|
} else {
|
|
|
|
inactive_nsid = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (active_nsid && inactive_nsid) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ns_data = spdk_dma_zmalloc(sizeof(*ns_data), 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ns_data != NULL);
|
|
|
|
|
|
|
|
/* NSID is 0, invalid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_IDENTIFY;
|
|
|
|
cmd.nsid = 0;
|
|
|
|
cmd.cdw10_bits.identify.cns = SPDK_NVME_IDENTIFY_NS;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, ns_data,
|
|
|
|
sizeof(*ns_data), test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT);
|
|
|
|
|
|
|
|
/* NSID is 0xffffffff, up to OACS can support NS MANAGE or not */
|
|
|
|
cmd.nsid = 0xffffffff;
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, ns_data,
|
|
|
|
sizeof(*ns_data), test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
if (!cdata->oacs.ns_manage) {
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT);
|
|
|
|
} else {
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* NSID is active, valid */
|
|
|
|
if (active_nsid) {
|
|
|
|
cmd.nsid = active_nsid;
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, ns_data,
|
|
|
|
sizeof(*ns_data), test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
2021-11-04 14:52:45 +00:00
|
|
|
|
|
|
|
max_xfer_size = spdk_nvme_ctrlr_get_max_xfer_size(ctrlr);
|
|
|
|
ns = spdk_nvme_ctrlr_get_ns(ctrlr, active_nsid);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ns != NULL);
|
|
|
|
|
|
|
|
if (ns_data->nsfeat.optperf) {
|
|
|
|
npwg = ns_data->npwg + 1;
|
|
|
|
nows = ns_data->nows + 1;
|
|
|
|
|
|
|
|
CU_ASSERT(npwg * spdk_nvme_ns_get_sector_size(ns) <= max_xfer_size);
|
|
|
|
CU_ASSERT(nows * spdk_nvme_ns_get_sector_size(ns) <= max_xfer_size);
|
|
|
|
CU_ASSERT(nows % npwg == 0);
|
|
|
|
}
|
2021-11-02 13:17:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* NSID is inactive, valid and should contain zeroed data */
|
|
|
|
if (inactive_nsid) {
|
|
|
|
memset(ns_data, 0x5A, sizeof(*ns_data));
|
|
|
|
cmd.nsid = inactive_nsid;
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, ns_data,
|
|
|
|
sizeof(*ns_data), test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
CU_ASSERT(spdk_mem_all_zero(ns_data, sizeof(*ns_data)));
|
|
|
|
}
|
|
|
|
|
|
|
|
spdk_dma_free(ns_data);
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-11-25 01:40:59 +00:00
|
|
|
/* Mandatory Log Page Identifiers
|
2021-11-03 13:17:15 +00:00
|
|
|
* 01h Error Information
|
|
|
|
* 02h SMART / Health Information
|
|
|
|
* 03h Firmware Slot Information
|
|
|
|
*/
|
|
|
|
static void
|
2021-11-09 14:47:30 +00:00
|
|
|
admin_get_log_page_mandatory_logs(void)
|
2021-11-03 13:17:15 +00:00
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
void *buf;
|
|
|
|
struct status s;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
buf = spdk_dma_zmalloc(0x1000, 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
|
|
|
|
|
|
|
/* 01h Error Information, valid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE;
|
|
|
|
cmd.cdw10_bits.get_log_page.numdl = sizeof(struct spdk_nvme_error_information_entry) / 4 - 1;
|
|
|
|
cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_ERROR;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, buf,
|
|
|
|
sizeof(struct spdk_nvme_error_information_entry), test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
2021-11-15 12:13:23 +00:00
|
|
|
/* 02h SMART / Health Information, valid */
|
|
|
|
cmd.cdw10_bits.get_log_page.numdl = sizeof(struct spdk_nvme_health_information_page) / 4 - 1;
|
|
|
|
cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_HEALTH_INFORMATION;
|
|
|
|
|
2021-11-03 13:17:15 +00:00
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, buf,
|
2021-11-15 12:13:23 +00:00
|
|
|
sizeof(struct spdk_nvme_health_information_page), test_cb, &s);
|
2021-11-03 13:17:15 +00:00
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
2021-11-15 12:13:23 +00:00
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
2021-11-03 13:17:15 +00:00
|
|
|
|
2021-11-15 12:13:23 +00:00
|
|
|
/* 03h Firmware Slot Information, valid */
|
|
|
|
cmd.cdw10_bits.get_log_page.numdl = sizeof(struct spdk_nvme_firmware_page) / 4 - 1;
|
|
|
|
cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_FIRMWARE_SLOT;
|
2021-11-03 13:17:15 +00:00
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, buf,
|
2021-11-15 12:13:23 +00:00
|
|
|
sizeof(struct spdk_nvme_firmware_page), test_cb, &s);
|
2021-11-03 13:17:15 +00:00
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
2021-11-15 12:13:23 +00:00
|
|
|
spdk_dma_free(buf);
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
admin_get_log_page_with_lpo(void)
|
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
void *buf;
|
|
|
|
struct status s;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
buf = spdk_dma_zmalloc(0x1000, 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
|
|
|
|
2021-11-03 13:17:15 +00:00
|
|
|
/* 03h Firmware Slot Information, valid */
|
2021-11-15 12:13:23 +00:00
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE;
|
2021-11-03 13:17:15 +00:00
|
|
|
cmd.cdw10_bits.get_log_page.numdl = sizeof(struct spdk_nvme_firmware_page) / 4 - 1;
|
|
|
|
cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_FIRMWARE_SLOT;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, buf,
|
|
|
|
sizeof(struct spdk_nvme_firmware_page), test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
2021-11-15 12:13:23 +00:00
|
|
|
/* Log Page Offset Lower is greater than spdk_nvme_firmware_page, invalid */
|
|
|
|
cmd.cdw12 = sizeof(struct spdk_nvme_firmware_page) + 4;
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, buf,
|
|
|
|
sizeof(struct spdk_nvme_firmware_page), test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD);
|
|
|
|
|
|
|
|
/* Log Page Offset Lower is less than spdk_nvme_firmware_page, but greater than 0, valid */
|
|
|
|
cmd.cdw12 = 4;
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, buf,
|
|
|
|
sizeof(struct spdk_nvme_firmware_page), test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
2021-11-03 13:17:15 +00:00
|
|
|
spdk_dma_free(buf);
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2021-12-03 12:29:09 +00:00
|
|
|
static void
|
|
|
|
admin_create_io_sq_shared_cq(void)
|
|
|
|
{
|
|
|
|
struct spdk_nvme_ctrlr *ctrlr;
|
|
|
|
struct spdk_nvme_cmd cmd;
|
|
|
|
void *buf;
|
|
|
|
uint64_t dma_addr;
|
|
|
|
struct status s;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
SPDK_CU_ASSERT_FATAL(spdk_nvme_transport_id_parse(&g_trid, g_trid_str) == 0);
|
|
|
|
ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
|
|
|
|
SPDK_CU_ASSERT_FATAL(ctrlr);
|
|
|
|
|
|
|
|
/* we will create 4 SQs and 2 CQs, each queue will use 1 page */
|
|
|
|
buf = spdk_dma_zmalloc(0x6000, 0x1000, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
|
|
|
dma_addr = nvme_vtophys(&g_trid, buf, NULL);
|
|
|
|
SPDK_CU_ASSERT_FATAL(dma_addr != SPDK_VTOPHYS_ERROR);
|
|
|
|
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_SET_FEATURES;
|
|
|
|
/* Number of Queues */
|
|
|
|
cmd.cdw10_bits.set_features.fid = SPDK_NVME_FEAT_NUMBER_OF_QUEUES;
|
|
|
|
cmd.cdw11_bits.feat_num_of_queues.bits.ncqr = 1; /* 0 based value */
|
|
|
|
cmd.cdw11_bits.feat_num_of_queues.bits.nsqr = 3; /* 0 based value */
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Create CQ 1, this is valid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_CREATE_IO_CQ;
|
|
|
|
cmd.cdw10_bits.create_io_q.qid = 1;
|
|
|
|
cmd.cdw10_bits.create_io_q.qsize = 7; /* 0 based value */
|
|
|
|
cmd.cdw11_bits.create_io_cq.pc = 1;
|
|
|
|
cmd.cdw11_bits.create_io_cq.ien = 1;
|
|
|
|
cmd.cdw11_bits.create_io_cq.iv = 1;
|
|
|
|
cmd.dptr.prp.prp1 = dma_addr;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Create CQ 2, this is valid */
|
|
|
|
cmd.cdw10_bits.create_io_q.qid = 2;
|
|
|
|
cmd.cdw11_bits.create_io_cq.iv = 2;
|
|
|
|
cmd.dptr.prp.prp1 = dma_addr + 0x1000;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Create SQ 1, CQID 2, this is valid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_CREATE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.create_io_q.qid = 1;
|
|
|
|
cmd.cdw10_bits.create_io_q.qsize = 7; /* 0 based value */
|
|
|
|
cmd.cdw11_bits.create_io_sq.pc = 1;
|
|
|
|
cmd.cdw11_bits.create_io_sq.cqid = 2;
|
|
|
|
cmd.dptr.prp.prp1 = dma_addr + 0x2000;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Create SQ 2, CQID 2, this is valid */
|
|
|
|
cmd.cdw10_bits.create_io_q.qid = 2;
|
|
|
|
cmd.dptr.prp.prp1 = dma_addr + 0x3000;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Create SQ 3, CQID 2, this is valid */
|
|
|
|
cmd.cdw10_bits.create_io_q.qid = 3;
|
|
|
|
cmd.dptr.prp.prp1 = dma_addr + 0x4000;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Create SQ 4, CQID 1, this is valid */
|
|
|
|
cmd.cdw10_bits.create_io_q.qid = 4;
|
|
|
|
cmd.cdw11_bits.create_io_sq.cqid = 1;
|
|
|
|
cmd.dptr.prp.prp1 = dma_addr + 0x5000;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Delete SQ 1, this is valid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 1;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Delete SQ 2, this is valid */
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 2;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Delete CQ 2, this is invalid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_CQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 2;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(s.cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
|
|
|
|
CU_ASSERT(s.cpl.status.sc == SPDK_NVME_SC_INVALID_QUEUE_DELETION);
|
|
|
|
|
|
|
|
/* Delete SQ 3, this is valid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 3;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Delete SQ 4, this is valid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_SQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 4;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Delete CQ 2, this is valid */
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
cmd.opc = SPDK_NVME_OPC_DELETE_IO_CQ;
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 2;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
/* Delete CQ 1, this is valid */
|
|
|
|
cmd.cdw10_bits.delete_io_q.qid = 1;
|
|
|
|
|
|
|
|
s.done = false;
|
|
|
|
rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, test_cb, &s);
|
|
|
|
CU_ASSERT(rc == 0);
|
|
|
|
wait_for_admin_completion(&s, ctrlr);
|
|
|
|
CU_ASSERT(!spdk_nvme_cpl_is_error(&s.cpl));
|
|
|
|
|
|
|
|
spdk_dma_free(buf);
|
|
|
|
spdk_nvme_detach(ctrlr);
|
|
|
|
}
|
|
|
|
|
2022-06-22 21:35:04 +00:00
|
|
|
int
|
|
|
|
main(int argc, char **argv)
|
2021-09-23 14:06:55 +00:00
|
|
|
{
|
|
|
|
struct spdk_env_opts opts;
|
|
|
|
CU_pSuite suite = NULL;
|
|
|
|
unsigned int num_failures;
|
|
|
|
|
|
|
|
CU_set_error_action(CUEA_ABORT);
|
|
|
|
CU_initialize_registry();
|
|
|
|
|
|
|
|
suite = CU_add_suite("nvme_compliance", NULL, NULL);
|
|
|
|
|
|
|
|
spdk_env_opts_init(&opts);
|
|
|
|
opts.name = "nvme_compliance";
|
|
|
|
if (parse_args(argc, argv, &opts)) {
|
|
|
|
fprintf(stderr, "could not parse_args\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_trid_str == NULL) {
|
|
|
|
fprintf(stderr, "-t <trid> not specified\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (spdk_env_init(&opts)) {
|
|
|
|
fprintf(stderr, "could not spdk_env_init\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2021-11-09 14:47:30 +00:00
|
|
|
CU_ADD_TEST(suite, admin_identify_ctrlr_verify_dptr);
|
|
|
|
CU_ADD_TEST(suite, admin_identify_ctrlr_verify_fused);
|
|
|
|
CU_ADD_TEST(suite, admin_identify_ns);
|
|
|
|
CU_ADD_TEST(suite, admin_get_features_mandatory_features);
|
|
|
|
CU_ADD_TEST(suite, admin_set_features_number_of_queues);
|
|
|
|
CU_ADD_TEST(suite, admin_get_log_page_mandatory_logs);
|
2021-11-15 12:13:23 +00:00
|
|
|
CU_ADD_TEST(suite, admin_get_log_page_with_lpo);
|
2021-11-09 14:47:30 +00:00
|
|
|
CU_ADD_TEST(suite, fabric_property_get);
|
|
|
|
CU_ADD_TEST(suite, admin_delete_io_sq_use_admin_qid);
|
|
|
|
CU_ADD_TEST(suite, admin_delete_io_sq_delete_sq_twice);
|
|
|
|
CU_ADD_TEST(suite, admin_delete_io_cq_use_admin_qid);
|
|
|
|
CU_ADD_TEST(suite, admin_delete_io_cq_delete_cq_first);
|
|
|
|
CU_ADD_TEST(suite, admin_create_io_cq_verify_iv_pc);
|
|
|
|
CU_ADD_TEST(suite, admin_create_io_sq_verify_qsize_cqid);
|
2021-11-09 15:57:31 +00:00
|
|
|
CU_ADD_TEST(suite, admin_create_io_sq_verify_pc);
|
2021-11-09 14:47:30 +00:00
|
|
|
CU_ADD_TEST(suite, admin_create_io_qp_max_qps);
|
2021-12-03 12:29:09 +00:00
|
|
|
CU_ADD_TEST(suite, admin_create_io_sq_shared_cq);
|
2021-09-23 14:06:55 +00:00
|
|
|
|
|
|
|
CU_basic_set_mode(CU_BRM_VERBOSE);
|
|
|
|
CU_basic_run_tests();
|
|
|
|
num_failures = CU_get_number_of_failures();
|
|
|
|
CU_cleanup_registry();
|
|
|
|
return num_failures;
|
|
|
|
}
|