1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse * Copyright (C) 2016 Intel Corporation.
38b0f2ad4SDaniel Verkamp * All rights reserved.
48b0f2ad4SDaniel Verkamp */
58b0f2ad4SDaniel Verkamp
68b0f2ad4SDaniel Verkamp #include "spdk/stdinc.h"
78b0f2ad4SDaniel Verkamp
8d998c1adSJim Harris #include "scsi/task.c"
9d998c1adSJim Harris #include "scsi/scsi_bdev.c"
107d468452SJim Harris #include "common/lib/test_env.c"
118b0f2ad4SDaniel Verkamp
12ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h"
138b0f2ad4SDaniel Verkamp
14760c8defSShuhei Matsumoto #include "spdk_internal/mock.h"
158a12e2e7SJim Harris #include "spdk/bdev_module.h"
16760c8defSShuhei Matsumoto
172172c432STomasz Zawadzki SPDK_LOG_REGISTER_COMPONENT(scsi)
188b0f2ad4SDaniel Verkamp
198b0f2ad4SDaniel Verkamp static uint64_t g_test_bdev_num_blocks;
208b0f2ad4SDaniel Verkamp
21a8656d66STomasz Zawadzki TAILQ_HEAD(, spdk_bdev_io) g_bdev_io_queue;
2273bc324bSShuhei Matsumoto int g_outstanding_bdev_io_count = 0;
23a8656d66STomasz Zawadzki int g_scsi_cb_called = 0;
24a8656d66STomasz Zawadzki
25f0ec7bc6STomasz Zawadzki TAILQ_HEAD(, spdk_bdev_io_wait_entry) g_io_wait_queue;
2673bc324bSShuhei Matsumoto int g_pending_bdev_io_count = 0;
27f0ec7bc6STomasz Zawadzki bool g_bdev_io_pool_full = false;
2873bc324bSShuhei Matsumoto int g_bdev_io_pool_count = -1;
29f0ec7bc6STomasz Zawadzki
308b0f2ad4SDaniel Verkamp bool
spdk_bdev_io_type_supported(struct spdk_bdev * bdev,enum spdk_bdev_io_type io_type)318b0f2ad4SDaniel Verkamp spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type)
328b0f2ad4SDaniel Verkamp {
338b0f2ad4SDaniel Verkamp abort();
348b0f2ad4SDaniel Verkamp return false;
358b0f2ad4SDaniel Verkamp }
368b0f2ad4SDaniel Verkamp
377a9ecf82SShuhei Matsumoto DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io));
388b0f2ad4SDaniel Verkamp
39760c8defSShuhei Matsumoto DEFINE_STUB(spdk_bdev_get_name, const char *,
40760c8defSShuhei Matsumoto (const struct spdk_bdev *bdev), "test");
418b0f2ad4SDaniel Verkamp
42760c8defSShuhei Matsumoto DEFINE_STUB(spdk_bdev_get_block_size, uint32_t,
43760c8defSShuhei Matsumoto (const struct spdk_bdev *bdev), 512);
448b0f2ad4SDaniel Verkamp
45986fb7b3SHaoqian He DEFINE_STUB(spdk_bdev_get_acwu, uint16_t,
46986fb7b3SHaoqian He (const struct spdk_bdev *bdev), 1);
47986fb7b3SHaoqian He
488697bce7SShuhei Matsumoto DEFINE_STUB(spdk_bdev_get_md_size, uint32_t,
498697bce7SShuhei Matsumoto (const struct spdk_bdev *bdev), 8);
508697bce7SShuhei Matsumoto
518697bce7SShuhei Matsumoto DEFINE_STUB(spdk_bdev_is_md_interleaved, bool,
528697bce7SShuhei Matsumoto (const struct spdk_bdev *bdev), false);
538697bce7SShuhei Matsumoto
54adc8da4aSShuhei Matsumoto DEFINE_STUB(spdk_bdev_get_data_block_size, uint32_t,
55adc8da4aSShuhei Matsumoto (const struct spdk_bdev *bdev), 512);
56adc8da4aSShuhei Matsumoto
576cebe9d0SSwapnil Ingle DEFINE_STUB(spdk_bdev_get_physical_block_size, uint32_t,
586cebe9d0SSwapnil Ingle (const struct spdk_bdev *bdev), 4096);
596cebe9d0SSwapnil Ingle
608b0f2ad4SDaniel Verkamp uint64_t
spdk_bdev_get_num_blocks(const struct spdk_bdev * bdev)618b0f2ad4SDaniel Verkamp spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev)
628b0f2ad4SDaniel Verkamp {
638b0f2ad4SDaniel Verkamp return g_test_bdev_num_blocks;
648b0f2ad4SDaniel Verkamp }
658b0f2ad4SDaniel Verkamp
66760c8defSShuhei Matsumoto DEFINE_STUB(spdk_bdev_get_product_name, const char *,
67760c8defSShuhei Matsumoto (const struct spdk_bdev *bdev), "test product");
688b0f2ad4SDaniel Verkamp
69760c8defSShuhei Matsumoto DEFINE_STUB(spdk_bdev_has_write_cache, bool,
70760c8defSShuhei Matsumoto (const struct spdk_bdev *bdev), false);
718b0f2ad4SDaniel Verkamp
728697bce7SShuhei Matsumoto DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type,
738697bce7SShuhei Matsumoto (const struct spdk_bdev *bdev), SPDK_DIF_DISABLE);
748697bce7SShuhei Matsumoto
758697bce7SShuhei Matsumoto DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool,
768697bce7SShuhei Matsumoto (const struct spdk_bdev *bdev), false);
778697bce7SShuhei Matsumoto
788697bce7SShuhei Matsumoto DEFINE_STUB(spdk_bdev_is_dif_check_enabled, bool,
798697bce7SShuhei Matsumoto (const struct spdk_bdev *bdev, enum spdk_dif_check_type check_type), false);
808697bce7SShuhei Matsumoto
8118dec401SShuhei Matsumoto DEFINE_STUB(scsi_pr_out, int, (struct spdk_scsi_task *task,
82d0d19eb8SChangpeng Liu uint8_t *cdb, uint8_t *data, uint16_t data_len), 0);
83d0d19eb8SChangpeng Liu
8418dec401SShuhei Matsumoto DEFINE_STUB(scsi_pr_in, int, (struct spdk_scsi_task *task, uint8_t *cdb,
854e9e220eSChangpeng Liu uint8_t *data, uint16_t data_len), 0);
864e9e220eSChangpeng Liu
876b6a3ff9SChangpeng Liu DEFINE_STUB(scsi2_reserve, int, (struct spdk_scsi_task *task, uint8_t *cdb), 0);
886b6a3ff9SChangpeng Liu DEFINE_STUB(scsi2_release, int, (struct spdk_scsi_task *task), 0);
896b6a3ff9SChangpeng Liu
908b0f2ad4SDaniel Verkamp void
scsi_lun_complete_task(struct spdk_scsi_lun * lun,struct spdk_scsi_task * task)9118dec401SShuhei Matsumoto scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)
928b0f2ad4SDaniel Verkamp {
93a8656d66STomasz Zawadzki g_scsi_cb_called++;
948b0f2ad4SDaniel Verkamp }
958b0f2ad4SDaniel Verkamp
9618dec401SShuhei Matsumoto DEFINE_STUB_V(scsi_lun_complete_reset_task,
97760c8defSShuhei Matsumoto (struct spdk_scsi_lun *lun, struct spdk_scsi_task *task));
988b0f2ad4SDaniel Verkamp
9912ab86e2SShuhei Matsumoto DEFINE_STUB(spdk_scsi_lun_id_int_to_fmt, uint64_t, (int lun_id), 0);
10012ab86e2SShuhei Matsumoto
101845db70cSShuhei Matsumoto DEFINE_STUB(spdk_scsi_dev_get_first_lun, struct spdk_scsi_lun *,
102845db70cSShuhei Matsumoto (struct spdk_scsi_dev *dev), NULL);
103845db70cSShuhei Matsumoto
104845db70cSShuhei Matsumoto DEFINE_STUB(spdk_scsi_dev_get_next_lun, struct spdk_scsi_lun *,
105845db70cSShuhei Matsumoto (struct spdk_scsi_lun *prev_lun), NULL);
106845db70cSShuhei Matsumoto
107757d23d0Szhenwei pi DEFINE_STUB(spdk_scsi_sbc_opcode_string, const char *,
108757d23d0Szhenwei pi (uint8_t opcode, uint16_t sa), "UNKNOWN");
109757d23d0Szhenwei pi
1108b0f2ad4SDaniel Verkamp static void
ut_put_task(struct spdk_scsi_task * task)111d5471e29STomasz Zawadzki ut_put_task(struct spdk_scsi_task *task)
1128b0f2ad4SDaniel Verkamp {
11359970a89SDaniel Verkamp if (task->alloc_len) {
1148b0f2ad4SDaniel Verkamp free(task->iov.iov_base);
11559970a89SDaniel Verkamp }
1168b0f2ad4SDaniel Verkamp
1178b0f2ad4SDaniel Verkamp task->iov.iov_base = NULL;
1188b0f2ad4SDaniel Verkamp task->iov.iov_len = 0;
1198b0f2ad4SDaniel Verkamp task->alloc_len = 0;
120a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
1218b0f2ad4SDaniel Verkamp }
1228b0f2ad4SDaniel Verkamp
1238b0f2ad4SDaniel Verkamp static void
ut_init_task(struct spdk_scsi_task * task)124d5471e29STomasz Zawadzki ut_init_task(struct spdk_scsi_task *task)
1258b0f2ad4SDaniel Verkamp {
12697154b1fSTomasz Zawadzki memset(task, 0xFF, sizeof(*task));
12797154b1fSTomasz Zawadzki task->iov.iov_base = NULL;
1288b0f2ad4SDaniel Verkamp task->iovs = &task->iov;
1298b0f2ad4SDaniel Verkamp task->iovcnt = 1;
13097154b1fSTomasz Zawadzki task->alloc_len = 0;
13197154b1fSTomasz Zawadzki task->dxfer_dir = SPDK_SCSI_DIR_NONE;
1328b0f2ad4SDaniel Verkamp }
1338b0f2ad4SDaniel Verkamp
1348b0f2ad4SDaniel Verkamp void
spdk_bdev_io_get_scsi_status(const struct spdk_bdev_io * bdev_io,int * sc,int * sk,int * asc,int * ascq)1358b0f2ad4SDaniel Verkamp spdk_bdev_io_get_scsi_status(const struct spdk_bdev_io *bdev_io,
1368b0f2ad4SDaniel Verkamp int *sc, int *sk, int *asc, int *ascq)
1378b0f2ad4SDaniel Verkamp {
13890906933SSeth Howell switch (bdev_io->internal.status) {
1398b0f2ad4SDaniel Verkamp case SPDK_BDEV_IO_STATUS_SUCCESS:
1408b0f2ad4SDaniel Verkamp *sc = SPDK_SCSI_STATUS_GOOD;
1418b0f2ad4SDaniel Verkamp *sk = SPDK_SCSI_SENSE_NO_SENSE;
1428b0f2ad4SDaniel Verkamp *asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
1438b0f2ad4SDaniel Verkamp *ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
1448b0f2ad4SDaniel Verkamp break;
145986fb7b3SHaoqian He case SPDK_BDEV_IO_STATUS_MISCOMPARE:
146986fb7b3SHaoqian He *sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
147986fb7b3SHaoqian He *sk = SPDK_SCSI_SENSE_MISCOMPARE;
148986fb7b3SHaoqian He *asc = SPDK_SCSI_ASC_MISCOMPARE_DURING_VERIFY_OPERATION;
149986fb7b3SHaoqian He *ascq = bdev_io->internal.error.scsi.ascq;
150986fb7b3SHaoqian He break;
1518b0f2ad4SDaniel Verkamp case SPDK_BDEV_IO_STATUS_SCSI_ERROR:
152816c34cbSSeth Howell *sc = bdev_io->internal.error.scsi.sc;
153816c34cbSSeth Howell *sk = bdev_io->internal.error.scsi.sk;
154816c34cbSSeth Howell *asc = bdev_io->internal.error.scsi.asc;
155816c34cbSSeth Howell *ascq = bdev_io->internal.error.scsi.ascq;
1568b0f2ad4SDaniel Verkamp break;
1578b0f2ad4SDaniel Verkamp default:
1588b0f2ad4SDaniel Verkamp *sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
1598b0f2ad4SDaniel Verkamp *sk = SPDK_SCSI_SENSE_ABORTED_COMMAND;
1608b0f2ad4SDaniel Verkamp *asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
1618b0f2ad4SDaniel Verkamp *ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
1628b0f2ad4SDaniel Verkamp break;
1638b0f2ad4SDaniel Verkamp }
1648b0f2ad4SDaniel Verkamp }
1658b0f2ad4SDaniel Verkamp
1668b0f2ad4SDaniel Verkamp void
spdk_bdev_io_get_iovec(struct spdk_bdev_io * bdev_io,struct iovec ** iovp,int * iovcntp)1678b0f2ad4SDaniel Verkamp spdk_bdev_io_get_iovec(struct spdk_bdev_io *bdev_io, struct iovec **iovp, int *iovcntp)
1688b0f2ad4SDaniel Verkamp {
1698b0f2ad4SDaniel Verkamp *iovp = NULL;
1708b0f2ad4SDaniel Verkamp *iovcntp = 0;
1718b0f2ad4SDaniel Verkamp }
1728b0f2ad4SDaniel Verkamp
173a8656d66STomasz Zawadzki static void
ut_bdev_io_complete(void)17473bc324bSShuhei Matsumoto ut_bdev_io_complete(void)
175a8656d66STomasz Zawadzki {
176a8656d66STomasz Zawadzki struct spdk_bdev_io *bdev_io;
177a8656d66STomasz Zawadzki
178a8656d66STomasz Zawadzki while (!TAILQ_EMPTY(&g_bdev_io_queue)) {
179a8656d66STomasz Zawadzki bdev_io = TAILQ_FIRST(&g_bdev_io_queue);
180a8656d66STomasz Zawadzki TAILQ_REMOVE(&g_bdev_io_queue, bdev_io, internal.link);
181a8656d66STomasz Zawadzki bdev_io->internal.cb(bdev_io, true, bdev_io->internal.caller_ctx);
182a8656d66STomasz Zawadzki free(bdev_io);
18373bc324bSShuhei Matsumoto g_outstanding_bdev_io_count--;
18473bc324bSShuhei Matsumoto if (g_bdev_io_pool_count != -1) {
18573bc324bSShuhei Matsumoto g_bdev_io_pool_count++;
186a8656d66STomasz Zawadzki }
18773bc324bSShuhei Matsumoto }
18873bc324bSShuhei Matsumoto }
18973bc324bSShuhei Matsumoto
19073bc324bSShuhei Matsumoto static void
ut_bdev_io_retry(void)19173bc324bSShuhei Matsumoto ut_bdev_io_retry(void)
19273bc324bSShuhei Matsumoto {
19373bc324bSShuhei Matsumoto struct spdk_bdev_io_wait_entry *entry;
194f0ec7bc6STomasz Zawadzki
195f0ec7bc6STomasz Zawadzki while (!TAILQ_EMPTY(&g_io_wait_queue)) {
196f0ec7bc6STomasz Zawadzki entry = TAILQ_FIRST(&g_io_wait_queue);
197f0ec7bc6STomasz Zawadzki TAILQ_REMOVE(&g_io_wait_queue, entry, link);
19873bc324bSShuhei Matsumoto g_pending_bdev_io_count--;
199f0ec7bc6STomasz Zawadzki entry->cb_fn(entry->cb_arg);
200f0ec7bc6STomasz Zawadzki }
201f0ec7bc6STomasz Zawadzki }
20273bc324bSShuhei Matsumoto
20373bc324bSShuhei Matsumoto static void
ut_bdev_io_flush(void)20473bc324bSShuhei Matsumoto ut_bdev_io_flush(void)
20573bc324bSShuhei Matsumoto {
20673bc324bSShuhei Matsumoto while (!TAILQ_EMPTY(&g_bdev_io_queue) || !TAILQ_EMPTY(&g_io_wait_queue)) {
20773bc324bSShuhei Matsumoto ut_bdev_io_complete();
20873bc324bSShuhei Matsumoto ut_bdev_io_retry();
20973bc324bSShuhei Matsumoto }
210a8656d66STomasz Zawadzki }
211a8656d66STomasz Zawadzki
212a8656d66STomasz Zawadzki static int
_spdk_bdev_io_op(spdk_bdev_io_completion_cb cb,void * cb_arg)213a8656d66STomasz Zawadzki _spdk_bdev_io_op(spdk_bdev_io_completion_cb cb, void *cb_arg)
214a8656d66STomasz Zawadzki {
215a8656d66STomasz Zawadzki struct spdk_bdev_io *bdev_io;
216a8656d66STomasz Zawadzki
217f0ec7bc6STomasz Zawadzki if (g_bdev_io_pool_full) {
218f0ec7bc6STomasz Zawadzki g_bdev_io_pool_full = false;
219f0ec7bc6STomasz Zawadzki return -ENOMEM;
22073bc324bSShuhei Matsumoto } else if (g_bdev_io_pool_count == 0) {
22173bc324bSShuhei Matsumoto return -ENOMEM;
22273bc324bSShuhei Matsumoto } else if (g_bdev_io_pool_count != -1) {
22373bc324bSShuhei Matsumoto g_bdev_io_pool_count--;
224f0ec7bc6STomasz Zawadzki }
225f0ec7bc6STomasz Zawadzki
226a8656d66STomasz Zawadzki bdev_io = calloc(1, sizeof(*bdev_io));
227a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
228a8656d66STomasz Zawadzki bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
229a8656d66STomasz Zawadzki bdev_io->internal.cb = cb;
230a8656d66STomasz Zawadzki bdev_io->internal.caller_ctx = cb_arg;
231a8656d66STomasz Zawadzki
232a8656d66STomasz Zawadzki TAILQ_INSERT_TAIL(&g_bdev_io_queue, bdev_io, internal.link);
23373bc324bSShuhei Matsumoto g_outstanding_bdev_io_count++;
234a8656d66STomasz Zawadzki
235a8656d66STomasz Zawadzki return 0;
236a8656d66STomasz Zawadzki }
237a8656d66STomasz Zawadzki
2388b0f2ad4SDaniel Verkamp int
spdk_bdev_readv_blocks(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,struct iovec * iov,int iovcnt,uint64_t offset_blocks,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)23956e12b00SShuhei Matsumoto spdk_bdev_readv_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
24056e12b00SShuhei Matsumoto struct iovec *iov, int iovcnt,
24156e12b00SShuhei Matsumoto uint64_t offset_blocks, uint64_t num_blocks,
2428b0f2ad4SDaniel Verkamp spdk_bdev_io_completion_cb cb, void *cb_arg)
2438b0f2ad4SDaniel Verkamp {
244a8656d66STomasz Zawadzki return _spdk_bdev_io_op(cb, cb_arg);
2458b0f2ad4SDaniel Verkamp }
2468b0f2ad4SDaniel Verkamp
2478b0f2ad4SDaniel Verkamp int
spdk_bdev_writev_blocks(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,struct iovec * iov,int iovcnt,uint64_t offset_blocks,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)24807e9a00bSShuhei Matsumoto spdk_bdev_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
2498b0f2ad4SDaniel Verkamp struct iovec *iov, int iovcnt,
25007e9a00bSShuhei Matsumoto uint64_t offset_blocks, uint64_t num_blocks,
2518b0f2ad4SDaniel Verkamp spdk_bdev_io_completion_cb cb, void *cb_arg)
2528b0f2ad4SDaniel Verkamp {
253a8656d66STomasz Zawadzki return _spdk_bdev_io_op(cb, cb_arg);
2548b0f2ad4SDaniel Verkamp }
2558b0f2ad4SDaniel Verkamp
2568b0f2ad4SDaniel Verkamp int
spdk_bdev_comparev_and_writev_blocks(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,struct iovec * compare_iov,int compare_iovcnt,struct iovec * write_iov,int write_iovcnt,uint64_t offset_blocks,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)257986fb7b3SHaoqian He spdk_bdev_comparev_and_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
258986fb7b3SHaoqian He struct iovec *compare_iov, int compare_iovcnt,
259986fb7b3SHaoqian He struct iovec *write_iov, int write_iovcnt,
260986fb7b3SHaoqian He uint64_t offset_blocks, uint64_t num_blocks,
261986fb7b3SHaoqian He spdk_bdev_io_completion_cb cb, void *cb_arg)
262986fb7b3SHaoqian He {
263986fb7b3SHaoqian He return _spdk_bdev_io_op(cb, cb_arg);
264986fb7b3SHaoqian He }
265986fb7b3SHaoqian He
266986fb7b3SHaoqian He int
spdk_bdev_unmap_blocks(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,uint64_t offset_blocks,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)26797f145c8SDaniel Verkamp spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
26897f145c8SDaniel Verkamp uint64_t offset_blocks, uint64_t num_blocks,
2698b0f2ad4SDaniel Verkamp spdk_bdev_io_completion_cb cb, void *cb_arg)
2708b0f2ad4SDaniel Verkamp {
271a8656d66STomasz Zawadzki return _spdk_bdev_io_op(cb, cb_arg);
2728b0f2ad4SDaniel Verkamp }
2738b0f2ad4SDaniel Verkamp
2748b0f2ad4SDaniel Verkamp int
spdk_bdev_reset(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,spdk_bdev_io_completion_cb cb,void * cb_arg)275be9a3b9fSJim Harris spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
2768b0f2ad4SDaniel Verkamp spdk_bdev_io_completion_cb cb, void *cb_arg)
2778b0f2ad4SDaniel Verkamp {
278a8656d66STomasz Zawadzki return _spdk_bdev_io_op(cb, cb_arg);
2798b0f2ad4SDaniel Verkamp }
2808b0f2ad4SDaniel Verkamp
2818b0f2ad4SDaniel Verkamp int
spdk_bdev_flush_blocks(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,uint64_t offset_blocks,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)282a520198dSDaniel Verkamp spdk_bdev_flush_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
283a520198dSDaniel Verkamp uint64_t offset_blocks, uint64_t num_blocks,
2848b0f2ad4SDaniel Verkamp spdk_bdev_io_completion_cb cb, void *cb_arg)
2858b0f2ad4SDaniel Verkamp {
286a8656d66STomasz Zawadzki return _spdk_bdev_io_op(cb, cb_arg);
2878b0f2ad4SDaniel Verkamp }
2888b0f2ad4SDaniel Verkamp
289f0ec7bc6STomasz Zawadzki int
spdk_bdev_queue_io_wait(struct spdk_bdev * bdev,struct spdk_io_channel * ch,struct spdk_bdev_io_wait_entry * entry)290f0ec7bc6STomasz Zawadzki spdk_bdev_queue_io_wait(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
291f0ec7bc6STomasz Zawadzki struct spdk_bdev_io_wait_entry *entry)
292f0ec7bc6STomasz Zawadzki {
293f0ec7bc6STomasz Zawadzki TAILQ_INSERT_TAIL(&g_io_wait_queue, entry, link);
29473bc324bSShuhei Matsumoto g_pending_bdev_io_count++;
295f0ec7bc6STomasz Zawadzki return 0;
296f0ec7bc6STomasz Zawadzki }
297f0ec7bc6STomasz Zawadzki
2988697bce7SShuhei Matsumoto int
spdk_dif_ctx_init(struct spdk_dif_ctx * ctx,uint32_t block_size,uint32_t md_size,bool md_interleave,bool dif_loc,enum spdk_dif_type dif_type,uint32_t dif_flags,uint32_t init_ref_tag,uint16_t apptag_mask,uint16_t app_tag,uint32_t data_offset,uint64_t guard_seed,struct spdk_dif_ctx_init_ext_opts * opts)2998697bce7SShuhei Matsumoto spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size,
3008697bce7SShuhei Matsumoto bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
3018697bce7SShuhei Matsumoto uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag,
3025256f0efSSlawomir Ptak uint32_t data_offset, uint64_t guard_seed, struct spdk_dif_ctx_init_ext_opts *opts)
3038697bce7SShuhei Matsumoto {
304a711d629SSlawomir Ptak ctx->dif_pi_format = opts->dif_pi_format;
3058697bce7SShuhei Matsumoto ctx->init_ref_tag = init_ref_tag;
30637bdd0e8SShuhei Matsumoto ctx->ref_tag_offset = data_offset / 512;
3078697bce7SShuhei Matsumoto return 0;
3088697bce7SShuhei Matsumoto }
3098697bce7SShuhei Matsumoto
3108b0f2ad4SDaniel Verkamp /*
3118b0f2ad4SDaniel Verkamp * This test specifically tests a mode select 6 command from the
3128b0f2ad4SDaniel Verkamp * Windows SCSI compliance test that caused SPDK to crash.
3138b0f2ad4SDaniel Verkamp */
3148b0f2ad4SDaniel Verkamp static void
mode_select_6_test(void)3158b0f2ad4SDaniel Verkamp mode_select_6_test(void)
3168b0f2ad4SDaniel Verkamp {
3178b0f2ad4SDaniel Verkamp struct spdk_bdev bdev;
3188b0f2ad4SDaniel Verkamp struct spdk_scsi_task task;
3198b0f2ad4SDaniel Verkamp struct spdk_scsi_lun lun;
3208b0f2ad4SDaniel Verkamp struct spdk_scsi_dev dev;
3218b0f2ad4SDaniel Verkamp char cdb[16];
3228b0f2ad4SDaniel Verkamp char data[24];
3238b0f2ad4SDaniel Verkamp int rc;
3248b0f2ad4SDaniel Verkamp
325d5471e29STomasz Zawadzki ut_init_task(&task);
3268b0f2ad4SDaniel Verkamp
3278b0f2ad4SDaniel Verkamp cdb[0] = 0x15;
3288b0f2ad4SDaniel Verkamp cdb[1] = 0x11;
3298b0f2ad4SDaniel Verkamp cdb[2] = 0x00;
3308b0f2ad4SDaniel Verkamp cdb[3] = 0x00;
3318b0f2ad4SDaniel Verkamp cdb[4] = 0x18;
3328b0f2ad4SDaniel Verkamp cdb[5] = 0x00;
3338b0f2ad4SDaniel Verkamp task.cdb = cdb;
3348b0f2ad4SDaniel Verkamp
3358b0f2ad4SDaniel Verkamp snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
336d57306d8SDaniel Verkamp lun.bdev = &bdev;
3378b0f2ad4SDaniel Verkamp lun.dev = &dev;
3388b0f2ad4SDaniel Verkamp task.lun = &lun;
3398b0f2ad4SDaniel Verkamp
3408b0f2ad4SDaniel Verkamp memset(data, 0, sizeof(data));
3418b0f2ad4SDaniel Verkamp data[4] = 0x08;
3428b0f2ad4SDaniel Verkamp data[5] = 0x02;
3438b0f2ad4SDaniel Verkamp spdk_scsi_task_set_data(&task, data, sizeof(data));
3448b0f2ad4SDaniel Verkamp
34518dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
3468b0f2ad4SDaniel Verkamp
3478b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(rc, 0);
3488b0f2ad4SDaniel Verkamp
349d5471e29STomasz Zawadzki ut_put_task(&task);
3508b0f2ad4SDaniel Verkamp }
3518b0f2ad4SDaniel Verkamp
3528b0f2ad4SDaniel Verkamp /*
3538b0f2ad4SDaniel Verkamp * This test specifically tests a mode select 6 command which
3548b0f2ad4SDaniel Verkamp * contains no mode pages.
3558b0f2ad4SDaniel Verkamp */
3568b0f2ad4SDaniel Verkamp static void
mode_select_6_test2(void)3578b0f2ad4SDaniel Verkamp mode_select_6_test2(void)
3588b0f2ad4SDaniel Verkamp {
3598b0f2ad4SDaniel Verkamp struct spdk_bdev bdev;
3608b0f2ad4SDaniel Verkamp struct spdk_scsi_task task;
3618b0f2ad4SDaniel Verkamp struct spdk_scsi_lun lun;
3628b0f2ad4SDaniel Verkamp struct spdk_scsi_dev dev;
3638b0f2ad4SDaniel Verkamp char cdb[16];
3648b0f2ad4SDaniel Verkamp int rc;
3658b0f2ad4SDaniel Verkamp
366d5471e29STomasz Zawadzki ut_init_task(&task);
3678b0f2ad4SDaniel Verkamp
3688b0f2ad4SDaniel Verkamp cdb[0] = 0x15;
3698b0f2ad4SDaniel Verkamp cdb[1] = 0x00;
3708b0f2ad4SDaniel Verkamp cdb[2] = 0x00;
3718b0f2ad4SDaniel Verkamp cdb[3] = 0x00;
3728b0f2ad4SDaniel Verkamp cdb[4] = 0x00;
3738b0f2ad4SDaniel Verkamp cdb[5] = 0x00;
3748b0f2ad4SDaniel Verkamp task.cdb = cdb;
3758b0f2ad4SDaniel Verkamp
3768b0f2ad4SDaniel Verkamp snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
377d57306d8SDaniel Verkamp lun.bdev = &bdev;
3788b0f2ad4SDaniel Verkamp lun.dev = &dev;
3798b0f2ad4SDaniel Verkamp task.lun = &lun;
3808b0f2ad4SDaniel Verkamp
38118dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
3828b0f2ad4SDaniel Verkamp
3838b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(rc, 0);
3848b0f2ad4SDaniel Verkamp
385d5471e29STomasz Zawadzki ut_put_task(&task);
3868b0f2ad4SDaniel Verkamp }
3878b0f2ad4SDaniel Verkamp
3888b0f2ad4SDaniel Verkamp /*
3898b0f2ad4SDaniel Verkamp * This test specifically tests a mode sense 6 command which
3908b0f2ad4SDaniel Verkamp * return all subpage 00h mode pages.
3918b0f2ad4SDaniel Verkamp */
3928b0f2ad4SDaniel Verkamp static void
mode_sense_6_test(void)3938b0f2ad4SDaniel Verkamp mode_sense_6_test(void)
3948b0f2ad4SDaniel Verkamp {
3958b0f2ad4SDaniel Verkamp struct spdk_bdev bdev;
3968b0f2ad4SDaniel Verkamp struct spdk_scsi_task task;
3978b0f2ad4SDaniel Verkamp struct spdk_scsi_lun lun;
3988b0f2ad4SDaniel Verkamp struct spdk_scsi_dev dev;
3998b0f2ad4SDaniel Verkamp char cdb[12];
4008b0f2ad4SDaniel Verkamp unsigned char *data;
4018b0f2ad4SDaniel Verkamp int rc;
4028b0f2ad4SDaniel Verkamp unsigned char mode_data_len = 0;
4038b0f2ad4SDaniel Verkamp unsigned char medium_type = 0;
4048b0f2ad4SDaniel Verkamp unsigned char dev_specific_param = 0;
4058b0f2ad4SDaniel Verkamp unsigned char blk_descriptor_len = 0;
4068b0f2ad4SDaniel Verkamp
4078b0f2ad4SDaniel Verkamp memset(&bdev, 0, sizeof(struct spdk_bdev));
408d5471e29STomasz Zawadzki ut_init_task(&task);
4098b0f2ad4SDaniel Verkamp memset(cdb, 0, sizeof(cdb));
4108b0f2ad4SDaniel Verkamp
4118b0f2ad4SDaniel Verkamp cdb[0] = 0x1A;
4128b0f2ad4SDaniel Verkamp cdb[2] = 0x3F;
4138b0f2ad4SDaniel Verkamp cdb[4] = 0xFF;
4148b0f2ad4SDaniel Verkamp task.cdb = cdb;
4158b0f2ad4SDaniel Verkamp
4168b0f2ad4SDaniel Verkamp snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
417d57306d8SDaniel Verkamp lun.bdev = &bdev;
4188b0f2ad4SDaniel Verkamp lun.dev = &dev;
4198b0f2ad4SDaniel Verkamp task.lun = &lun;
4208b0f2ad4SDaniel Verkamp
42118dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
4228b0f2ad4SDaniel Verkamp SPDK_CU_ASSERT_FATAL(rc == 0);
4238b0f2ad4SDaniel Verkamp
4248b0f2ad4SDaniel Verkamp data = task.iovs[0].iov_base;
4258b0f2ad4SDaniel Verkamp mode_data_len = data[0];
4268b0f2ad4SDaniel Verkamp medium_type = data[1];
4278b0f2ad4SDaniel Verkamp dev_specific_param = data[2];
4288b0f2ad4SDaniel Verkamp blk_descriptor_len = data[3];
4298b0f2ad4SDaniel Verkamp
4308b0f2ad4SDaniel Verkamp CU_ASSERT(mode_data_len >= 11);
4318b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(medium_type, 0);
4328b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(dev_specific_param, 0);
4338b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(blk_descriptor_len, 8);
4348b0f2ad4SDaniel Verkamp
435d5471e29STomasz Zawadzki ut_put_task(&task);
4368b0f2ad4SDaniel Verkamp }
4378b0f2ad4SDaniel Verkamp
4388b0f2ad4SDaniel Verkamp /*
4398b0f2ad4SDaniel Verkamp * This test specifically tests a mode sense 10 command which
4408b0f2ad4SDaniel Verkamp * return all subpage 00h mode pages.
4418b0f2ad4SDaniel Verkamp */
4428b0f2ad4SDaniel Verkamp static void
mode_sense_10_test(void)4438b0f2ad4SDaniel Verkamp mode_sense_10_test(void)
4448b0f2ad4SDaniel Verkamp {
4458b0f2ad4SDaniel Verkamp struct spdk_bdev bdev;
4468b0f2ad4SDaniel Verkamp struct spdk_scsi_task task;
4478b0f2ad4SDaniel Verkamp struct spdk_scsi_lun lun;
4488b0f2ad4SDaniel Verkamp struct spdk_scsi_dev dev;
4498b0f2ad4SDaniel Verkamp char cdb[12];
4508b0f2ad4SDaniel Verkamp unsigned char *data;
4518b0f2ad4SDaniel Verkamp int rc;
4528b0f2ad4SDaniel Verkamp unsigned short mode_data_len = 0;
4538b0f2ad4SDaniel Verkamp unsigned char medium_type = 0;
4548b0f2ad4SDaniel Verkamp unsigned char dev_specific_param = 0;
4558b0f2ad4SDaniel Verkamp unsigned short blk_descriptor_len = 0;
4568b0f2ad4SDaniel Verkamp
4578b0f2ad4SDaniel Verkamp memset(&bdev, 0, sizeof(struct spdk_bdev));
458d5471e29STomasz Zawadzki ut_init_task(&task);
4598b0f2ad4SDaniel Verkamp memset(cdb, 0, sizeof(cdb));
4608b0f2ad4SDaniel Verkamp cdb[0] = 0x5A;
4618b0f2ad4SDaniel Verkamp cdb[2] = 0x3F;
4628b0f2ad4SDaniel Verkamp cdb[8] = 0xFF;
4638b0f2ad4SDaniel Verkamp task.cdb = cdb;
4648b0f2ad4SDaniel Verkamp
4658b0f2ad4SDaniel Verkamp snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
466d57306d8SDaniel Verkamp lun.bdev = &bdev;
4678b0f2ad4SDaniel Verkamp lun.dev = &dev;
4688b0f2ad4SDaniel Verkamp task.lun = &lun;
4698b0f2ad4SDaniel Verkamp
47018dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
4718b0f2ad4SDaniel Verkamp SPDK_CU_ASSERT_FATAL(rc == 0);
4728b0f2ad4SDaniel Verkamp
4738b0f2ad4SDaniel Verkamp data = task.iovs[0].iov_base;
4748b0f2ad4SDaniel Verkamp mode_data_len = ((data[0] << 8) + data[1]);
4758b0f2ad4SDaniel Verkamp medium_type = data[2];
4768b0f2ad4SDaniel Verkamp dev_specific_param = data[3];
4778b0f2ad4SDaniel Verkamp blk_descriptor_len = ((data[6] << 8) + data[7]);
4788b0f2ad4SDaniel Verkamp
4798b0f2ad4SDaniel Verkamp CU_ASSERT(mode_data_len >= 14);
4808b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(medium_type, 0);
4818b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(dev_specific_param, 0);
4828b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(blk_descriptor_len, 8);
4838b0f2ad4SDaniel Verkamp
484d5471e29STomasz Zawadzki ut_put_task(&task);
4858b0f2ad4SDaniel Verkamp }
4868b0f2ad4SDaniel Verkamp
4878b0f2ad4SDaniel Verkamp /*
4888b0f2ad4SDaniel Verkamp * This test specifically tests a scsi inquiry command from the
4898b0f2ad4SDaniel Verkamp * Windows SCSI compliance test that failed to return the
4908b0f2ad4SDaniel Verkamp * expected SCSI error sense code.
4918b0f2ad4SDaniel Verkamp */
4928b0f2ad4SDaniel Verkamp static void
inquiry_evpd_test(void)4938b0f2ad4SDaniel Verkamp inquiry_evpd_test(void)
4948b0f2ad4SDaniel Verkamp {
4958b0f2ad4SDaniel Verkamp struct spdk_bdev bdev;
4968b0f2ad4SDaniel Verkamp struct spdk_scsi_task task;
4978b0f2ad4SDaniel Verkamp struct spdk_scsi_lun lun;
4988b0f2ad4SDaniel Verkamp struct spdk_scsi_dev dev;
4998b0f2ad4SDaniel Verkamp char cdb[6];
5008b0f2ad4SDaniel Verkamp int rc;
5018b0f2ad4SDaniel Verkamp
502d5471e29STomasz Zawadzki ut_init_task(&task);
5038b0f2ad4SDaniel Verkamp
5048b0f2ad4SDaniel Verkamp cdb[0] = 0x12;
50565e5bbdcSShuhei Matsumoto cdb[1] = 0x00; /* EVPD = 0 */
50665e5bbdcSShuhei Matsumoto cdb[2] = 0xff; /* PageCode non-zero */
5078b0f2ad4SDaniel Verkamp cdb[3] = 0x00;
5088b0f2ad4SDaniel Verkamp cdb[4] = 0xff;
5098b0f2ad4SDaniel Verkamp cdb[5] = 0x00;
5108b0f2ad4SDaniel Verkamp task.cdb = cdb;
5118b0f2ad4SDaniel Verkamp
5128b0f2ad4SDaniel Verkamp snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
513d57306d8SDaniel Verkamp lun.bdev = &bdev;
5148b0f2ad4SDaniel Verkamp lun.dev = &dev;
5158b0f2ad4SDaniel Verkamp task.lun = &lun;
5168b0f2ad4SDaniel Verkamp
51718dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
5188b0f2ad4SDaniel Verkamp SPDK_CU_ASSERT_FATAL(rc == 0);
5198b0f2ad4SDaniel Verkamp
5208b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
5218b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ILLEGAL_REQUEST);
5228b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.sense_data[12], 0x24);
5238b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.sense_data[13], 0x0);
5248b0f2ad4SDaniel Verkamp
525d5471e29STomasz Zawadzki ut_put_task(&task);
5268b0f2ad4SDaniel Verkamp }
5278b0f2ad4SDaniel Verkamp
5288b0f2ad4SDaniel Verkamp /*
5298b0f2ad4SDaniel Verkamp * This test is to verify specific return data for a standard scsi inquiry
5308b0f2ad4SDaniel Verkamp * command: Version
5318b0f2ad4SDaniel Verkamp */
5328b0f2ad4SDaniel Verkamp static void
inquiry_standard_test(void)5338b0f2ad4SDaniel Verkamp inquiry_standard_test(void)
5348b0f2ad4SDaniel Verkamp {
5358b0f2ad4SDaniel Verkamp struct spdk_bdev bdev = { .blocklen = 512 };
5368b0f2ad4SDaniel Verkamp struct spdk_scsi_task task;
5378b0f2ad4SDaniel Verkamp struct spdk_scsi_lun lun;
5388b0f2ad4SDaniel Verkamp struct spdk_scsi_dev dev;
5398b0f2ad4SDaniel Verkamp char cdb[6];
5408b0f2ad4SDaniel Verkamp char *data;
5418b0f2ad4SDaniel Verkamp struct spdk_scsi_cdb_inquiry_data *inq_data;
5428b0f2ad4SDaniel Verkamp int rc;
5438b0f2ad4SDaniel Verkamp
544d5471e29STomasz Zawadzki ut_init_task(&task);
5458b0f2ad4SDaniel Verkamp
5468b0f2ad4SDaniel Verkamp cdb[0] = 0x12;
54765e5bbdcSShuhei Matsumoto cdb[1] = 0x00; /* EVPD = 0 */
54865e5bbdcSShuhei Matsumoto cdb[2] = 0x00; /* PageCode zero - requesting standard inquiry */
5498b0f2ad4SDaniel Verkamp cdb[3] = 0x00;
55065e5bbdcSShuhei Matsumoto cdb[4] = 0xff; /* Indicate data size used by conformance test */
5518b0f2ad4SDaniel Verkamp cdb[5] = 0x00;
5528b0f2ad4SDaniel Verkamp task.cdb = cdb;
5538b0f2ad4SDaniel Verkamp
5548b0f2ad4SDaniel Verkamp snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
555d57306d8SDaniel Verkamp lun.bdev = &bdev;
5568b0f2ad4SDaniel Verkamp lun.dev = &dev;
5578b0f2ad4SDaniel Verkamp task.lun = &lun;
5588b0f2ad4SDaniel Verkamp
55918dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
5608b0f2ad4SDaniel Verkamp
5618b0f2ad4SDaniel Verkamp data = task.iovs[0].iov_base;
5628b0f2ad4SDaniel Verkamp inq_data = (struct spdk_scsi_cdb_inquiry_data *)&data[0];
5638b0f2ad4SDaniel Verkamp
5648b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(inq_data->version, SPDK_SPC_VERSION_SPC3);
5658b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(rc, 0);
5668b0f2ad4SDaniel Verkamp
567d5471e29STomasz Zawadzki ut_put_task(&task);
5688b0f2ad4SDaniel Verkamp }
5698b0f2ad4SDaniel Verkamp
5708b0f2ad4SDaniel Verkamp static void
_inquiry_overflow_test(uint8_t alloc_len)5718b0f2ad4SDaniel Verkamp _inquiry_overflow_test(uint8_t alloc_len)
5728b0f2ad4SDaniel Verkamp {
5738b0f2ad4SDaniel Verkamp struct spdk_bdev bdev = { .blocklen = 512 };
5748b0f2ad4SDaniel Verkamp struct spdk_scsi_task task;
5758b0f2ad4SDaniel Verkamp struct spdk_scsi_lun lun;
5768b0f2ad4SDaniel Verkamp struct spdk_scsi_dev dev;
5778b0f2ad4SDaniel Verkamp uint8_t cdb[6];
5788b0f2ad4SDaniel Verkamp int rc;
5798b0f2ad4SDaniel Verkamp /* expects a 4K internal data buffer */
5808b0f2ad4SDaniel Verkamp char data[4096], data_compare[4096];
5818b0f2ad4SDaniel Verkamp
582d5471e29STomasz Zawadzki ut_init_task(&task);
5838b0f2ad4SDaniel Verkamp
5848b0f2ad4SDaniel Verkamp cdb[0] = 0x12;
58565e5bbdcSShuhei Matsumoto cdb[1] = 0x00; /* EVPD = 0 */
58665e5bbdcSShuhei Matsumoto cdb[2] = 0x00; /* PageCode zero - requesting standard inquiry */
5878b0f2ad4SDaniel Verkamp cdb[3] = 0x00;
58865e5bbdcSShuhei Matsumoto cdb[4] = alloc_len; /* Indicate data size used by conformance test */
5898b0f2ad4SDaniel Verkamp cdb[5] = 0x00;
5908b0f2ad4SDaniel Verkamp task.cdb = cdb;
5918b0f2ad4SDaniel Verkamp
5928b0f2ad4SDaniel Verkamp snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
593d57306d8SDaniel Verkamp lun.bdev = &bdev;
5948b0f2ad4SDaniel Verkamp lun.dev = &dev;
5958b0f2ad4SDaniel Verkamp task.lun = &lun;
5968b0f2ad4SDaniel Verkamp
5978b0f2ad4SDaniel Verkamp memset(data, 0, sizeof(data));
5988b0f2ad4SDaniel Verkamp memset(data_compare, 0, sizeof(data_compare));
5998b0f2ad4SDaniel Verkamp
6008b0f2ad4SDaniel Verkamp spdk_scsi_task_set_data(&task, data, sizeof(data));
6018b0f2ad4SDaniel Verkamp
60218dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
6038b0f2ad4SDaniel Verkamp SPDK_CU_ASSERT_FATAL(rc == 0);
6048b0f2ad4SDaniel Verkamp
6058b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(memcmp(data + alloc_len, data_compare + alloc_len, sizeof(data) - alloc_len), 0);
6068b0f2ad4SDaniel Verkamp CU_ASSERT(task.data_transferred <= alloc_len);
6078b0f2ad4SDaniel Verkamp
608d5471e29STomasz Zawadzki ut_put_task(&task);
6098b0f2ad4SDaniel Verkamp }
6108b0f2ad4SDaniel Verkamp
6118b0f2ad4SDaniel Verkamp static void
inquiry_overflow_test(void)6128b0f2ad4SDaniel Verkamp inquiry_overflow_test(void)
6138b0f2ad4SDaniel Verkamp {
6148b0f2ad4SDaniel Verkamp int i;
6158b0f2ad4SDaniel Verkamp
6168b0f2ad4SDaniel Verkamp for (i = 0; i < 256; i++) {
6178b0f2ad4SDaniel Verkamp _inquiry_overflow_test(i);
6188b0f2ad4SDaniel Verkamp }
6198b0f2ad4SDaniel Verkamp }
6208b0f2ad4SDaniel Verkamp
621c013db36SShuhei Matsumoto static void
scsi_name_padding_test(void)622c013db36SShuhei Matsumoto scsi_name_padding_test(void)
623c013db36SShuhei Matsumoto {
624af9c9a41SDaniel Verkamp char name[SPDK_SCSI_DEV_MAX_NAME + 1];
625c013db36SShuhei Matsumoto char buf[SPDK_SCSI_DEV_MAX_NAME + 1];
626c013db36SShuhei Matsumoto int written, i;
627c013db36SShuhei Matsumoto
628c013db36SShuhei Matsumoto /* case 1 */
629c013db36SShuhei Matsumoto memset(name, '\0', sizeof(name));
630c013db36SShuhei Matsumoto memset(name, 'x', 251);
6310ed66e7eSShuhei Matsumoto written = bdev_scsi_pad_scsi_name(buf, name);
632c013db36SShuhei Matsumoto
633c013db36SShuhei Matsumoto CU_ASSERT(written == 252);
634c013db36SShuhei Matsumoto CU_ASSERT(buf[250] == 'x');
635c013db36SShuhei Matsumoto CU_ASSERT(buf[251] == '\0');
636c013db36SShuhei Matsumoto
637c013db36SShuhei Matsumoto /* case 2: */
638c013db36SShuhei Matsumoto memset(name, '\0', sizeof(name));
639c013db36SShuhei Matsumoto memset(name, 'x', 252);
6400ed66e7eSShuhei Matsumoto written = bdev_scsi_pad_scsi_name(buf, name);
641c013db36SShuhei Matsumoto
642c013db36SShuhei Matsumoto CU_ASSERT(written == 256);
643c013db36SShuhei Matsumoto CU_ASSERT(buf[251] == 'x');
644c013db36SShuhei Matsumoto for (i = 252; i < 256; i++) {
645c013db36SShuhei Matsumoto CU_ASSERT(buf[i] == '\0');
646c013db36SShuhei Matsumoto }
647c013db36SShuhei Matsumoto
648c013db36SShuhei Matsumoto /* case 3 */
649c013db36SShuhei Matsumoto memset(name, '\0', sizeof(name));
650c013db36SShuhei Matsumoto memset(name, 'x', 255);
6510ed66e7eSShuhei Matsumoto written = bdev_scsi_pad_scsi_name(buf, name);
652c013db36SShuhei Matsumoto
653c013db36SShuhei Matsumoto CU_ASSERT(written == 256);
654c013db36SShuhei Matsumoto CU_ASSERT(buf[254] == 'x');
655c013db36SShuhei Matsumoto CU_ASSERT(buf[255] == '\0');
656c013db36SShuhei Matsumoto }
657c013db36SShuhei Matsumoto
6588b0f2ad4SDaniel Verkamp /*
6598b0f2ad4SDaniel Verkamp * This test is to verify specific error translation from bdev to scsi.
6608b0f2ad4SDaniel Verkamp */
6618b0f2ad4SDaniel Verkamp static void
task_complete_test(void)6628b0f2ad4SDaniel Verkamp task_complete_test(void)
6638b0f2ad4SDaniel Verkamp {
6648b0f2ad4SDaniel Verkamp struct spdk_scsi_task task;
6658b0f2ad4SDaniel Verkamp struct spdk_bdev_io bdev_io = {};
6668b0f2ad4SDaniel Verkamp struct spdk_scsi_lun lun;
6678b0f2ad4SDaniel Verkamp
668d5471e29STomasz Zawadzki ut_init_task(&task);
6698b0f2ad4SDaniel Verkamp
6708b0f2ad4SDaniel Verkamp TAILQ_INIT(&lun.tasks);
6718b0f2ad4SDaniel Verkamp TAILQ_INSERT_TAIL(&lun.tasks, &task, scsi_link);
6728b0f2ad4SDaniel Verkamp task.lun = &lun;
6738b0f2ad4SDaniel Verkamp
67490906933SSeth Howell bdev_io.internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
6750ed66e7eSShuhei Matsumoto bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task);
6768b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD);
677a8656d66STomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
678a8656d66STomasz Zawadzki g_scsi_cb_called = 0;
6798b0f2ad4SDaniel Verkamp
68090906933SSeth Howell bdev_io.internal.status = SPDK_BDEV_IO_STATUS_SCSI_ERROR;
681816c34cbSSeth Howell bdev_io.internal.error.scsi.sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
682816c34cbSSeth Howell bdev_io.internal.error.scsi.sk = SPDK_SCSI_SENSE_HARDWARE_ERROR;
683816c34cbSSeth Howell bdev_io.internal.error.scsi.asc = SPDK_SCSI_ASC_WARNING;
684816c34cbSSeth Howell bdev_io.internal.error.scsi.ascq = SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED;
6850ed66e7eSShuhei Matsumoto bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task);
6868b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
6878b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_HARDWARE_ERROR);
6888b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_WARNING);
6898b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED);
690a8656d66STomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
691a8656d66STomasz Zawadzki g_scsi_cb_called = 0;
6928b0f2ad4SDaniel Verkamp
69390906933SSeth Howell bdev_io.internal.status = SPDK_BDEV_IO_STATUS_FAILED;
6940ed66e7eSShuhei Matsumoto bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task);
6958b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
6968b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ABORTED_COMMAND);
6978b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE);
6988b0f2ad4SDaniel Verkamp CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
699a8656d66STomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
700a8656d66STomasz Zawadzki g_scsi_cb_called = 0;
7018b0f2ad4SDaniel Verkamp
702d5471e29STomasz Zawadzki ut_put_task(&task);
7038b0f2ad4SDaniel Verkamp }
7048b0f2ad4SDaniel Verkamp
7058b0f2ad4SDaniel Verkamp static void
lba_range_test(void)7068b0f2ad4SDaniel Verkamp lba_range_test(void)
7078b0f2ad4SDaniel Verkamp {
70856e12b00SShuhei Matsumoto struct spdk_bdev bdev = { .blocklen = 512 };
709d57306d8SDaniel Verkamp struct spdk_scsi_lun lun;
7108b0f2ad4SDaniel Verkamp struct spdk_scsi_task task;
7118b0f2ad4SDaniel Verkamp uint8_t cdb[16];
7128b0f2ad4SDaniel Verkamp int rc;
7138b0f2ad4SDaniel Verkamp
714d57306d8SDaniel Verkamp lun.bdev = &bdev;
715d57306d8SDaniel Verkamp
716d5471e29STomasz Zawadzki ut_init_task(&task);
717d57306d8SDaniel Verkamp task.lun = &lun;
71817e9d38cSSeth Howell task.lun->bdev_desc = NULL;
71917e9d38cSSeth Howell task.lun->io_channel = NULL;
7208b0f2ad4SDaniel Verkamp task.cdb = cdb;
7218b0f2ad4SDaniel Verkamp
7228b0f2ad4SDaniel Verkamp memset(cdb, 0, sizeof(cdb));
7238b0f2ad4SDaniel Verkamp cdb[0] = 0x88; /* READ (16) */
7248b0f2ad4SDaniel Verkamp
7258b0f2ad4SDaniel Verkamp /* Test block device size of 4 blocks */
7268b0f2ad4SDaniel Verkamp g_test_bdev_num_blocks = 4;
7278b0f2ad4SDaniel Verkamp
7288b0f2ad4SDaniel Verkamp /* LBA = 0, length = 1 (in range) */
7298b0f2ad4SDaniel Verkamp to_be64(&cdb[2], 0); /* LBA */
7308b0f2ad4SDaniel Verkamp to_be32(&cdb[10], 1); /* transfer length */
7318b0f2ad4SDaniel Verkamp task.transfer_len = 1 * 512;
73256e12b00SShuhei Matsumoto task.offset = 0;
73356e12b00SShuhei Matsumoto task.length = 1 * 512;
73418dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
7358b0f2ad4SDaniel Verkamp CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
736bcfd6d0fSTomasz Zawadzki CU_ASSERT(task.status == 0xFF);
737a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
738a8656d66STomasz Zawadzki ut_bdev_io_flush();
739bcfd6d0fSTomasz Zawadzki CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
740a8656d66STomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
741a8656d66STomasz Zawadzki g_scsi_cb_called = 0;
7428b0f2ad4SDaniel Verkamp
7438b0f2ad4SDaniel Verkamp /* LBA = 4, length = 1 (LBA out of range) */
7448b0f2ad4SDaniel Verkamp to_be64(&cdb[2], 4); /* LBA */
7458b0f2ad4SDaniel Verkamp to_be32(&cdb[10], 1); /* transfer length */
7468b0f2ad4SDaniel Verkamp task.transfer_len = 1 * 512;
74756e12b00SShuhei Matsumoto task.offset = 0;
74856e12b00SShuhei Matsumoto task.length = 1 * 512;
74918dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
7508b0f2ad4SDaniel Verkamp CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
7518b0f2ad4SDaniel Verkamp CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
7528b0f2ad4SDaniel Verkamp CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
753a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
7548b0f2ad4SDaniel Verkamp
7558b0f2ad4SDaniel Verkamp /* LBA = 0, length = 4 (in range, max valid size) */
7568b0f2ad4SDaniel Verkamp to_be64(&cdb[2], 0); /* LBA */
7578b0f2ad4SDaniel Verkamp to_be32(&cdb[10], 4); /* transfer length */
7588b0f2ad4SDaniel Verkamp task.transfer_len = 4 * 512;
759bcfd6d0fSTomasz Zawadzki task.status = 0xFF;
76056e12b00SShuhei Matsumoto task.offset = 0;
76156e12b00SShuhei Matsumoto task.length = 1 * 512;
76218dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
7638b0f2ad4SDaniel Verkamp CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
764bcfd6d0fSTomasz Zawadzki CU_ASSERT(task.status == 0xFF);
765a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
766a8656d66STomasz Zawadzki ut_bdev_io_flush();
767bcfd6d0fSTomasz Zawadzki CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
768a8656d66STomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
769a8656d66STomasz Zawadzki g_scsi_cb_called = 0;
7708b0f2ad4SDaniel Verkamp
7718b0f2ad4SDaniel Verkamp /* LBA = 0, length = 5 (LBA in range, length beyond end of bdev) */
7728b0f2ad4SDaniel Verkamp to_be64(&cdb[2], 0); /* LBA */
7738b0f2ad4SDaniel Verkamp to_be32(&cdb[10], 5); /* transfer length */
7748b0f2ad4SDaniel Verkamp task.transfer_len = 5 * 512;
77556e12b00SShuhei Matsumoto task.offset = 0;
77656e12b00SShuhei Matsumoto task.length = 1 * 512;
77718dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
7788b0f2ad4SDaniel Verkamp CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
7798b0f2ad4SDaniel Verkamp CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
7808b0f2ad4SDaniel Verkamp CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
781a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
7828b0f2ad4SDaniel Verkamp
783d5471e29STomasz Zawadzki ut_put_task(&task);
7848b0f2ad4SDaniel Verkamp }
7858b0f2ad4SDaniel Verkamp
7860b1bbb45SDaniel Verkamp static void
xfer_len_test(void)7870b1bbb45SDaniel Verkamp xfer_len_test(void)
7880b1bbb45SDaniel Verkamp {
78956e12b00SShuhei Matsumoto struct spdk_bdev bdev = { .blocklen = 512 };
790d57306d8SDaniel Verkamp struct spdk_scsi_lun lun;
7910b1bbb45SDaniel Verkamp struct spdk_scsi_task task;
7920b1bbb45SDaniel Verkamp uint8_t cdb[16];
7930b1bbb45SDaniel Verkamp int rc;
7940b1bbb45SDaniel Verkamp
795d57306d8SDaniel Verkamp lun.bdev = &bdev;
796d57306d8SDaniel Verkamp
797d5471e29STomasz Zawadzki ut_init_task(&task);
798d57306d8SDaniel Verkamp task.lun = &lun;
79917e9d38cSSeth Howell task.lun->bdev_desc = NULL;
80017e9d38cSSeth Howell task.lun->io_channel = NULL;
8010b1bbb45SDaniel Verkamp task.cdb = cdb;
8020b1bbb45SDaniel Verkamp
8030b1bbb45SDaniel Verkamp memset(cdb, 0, sizeof(cdb));
8040b1bbb45SDaniel Verkamp cdb[0] = 0x88; /* READ (16) */
8050b1bbb45SDaniel Verkamp
8060b1bbb45SDaniel Verkamp /* Test block device size of 512 MiB */
8070b1bbb45SDaniel Verkamp g_test_bdev_num_blocks = 512 * 1024 * 1024;
8080b1bbb45SDaniel Verkamp
8090b1bbb45SDaniel Verkamp /* 1 block */
8100b1bbb45SDaniel Verkamp to_be64(&cdb[2], 0); /* LBA */
8110b1bbb45SDaniel Verkamp to_be32(&cdb[10], 1); /* transfer length */
8120b1bbb45SDaniel Verkamp task.transfer_len = 1 * 512;
81356e12b00SShuhei Matsumoto task.offset = 0;
81456e12b00SShuhei Matsumoto task.length = 1 * 512;
81518dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
8160b1bbb45SDaniel Verkamp CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
817bcfd6d0fSTomasz Zawadzki CU_ASSERT(task.status == 0xFF);
818a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
819a8656d66STomasz Zawadzki ut_bdev_io_flush();
820bcfd6d0fSTomasz Zawadzki CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
821a8656d66STomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
822a8656d66STomasz Zawadzki g_scsi_cb_called = 0;
8230b1bbb45SDaniel Verkamp
8240b1bbb45SDaniel Verkamp /* max transfer length (as reported in block limits VPD page) */
8250b1bbb45SDaniel Verkamp to_be64(&cdb[2], 0); /* LBA */
8260b1bbb45SDaniel Verkamp to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512); /* transfer length */
8270b1bbb45SDaniel Verkamp task.transfer_len = SPDK_WORK_BLOCK_SIZE;
828bcfd6d0fSTomasz Zawadzki task.status = 0xFF;
82956e12b00SShuhei Matsumoto task.offset = 0;
83056e12b00SShuhei Matsumoto task.length = 1 * 512;
83118dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
8320b1bbb45SDaniel Verkamp CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
833bcfd6d0fSTomasz Zawadzki CU_ASSERT(task.status == 0xFF);
834a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
835a8656d66STomasz Zawadzki ut_bdev_io_flush();
836bcfd6d0fSTomasz Zawadzki CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
837a8656d66STomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
838a8656d66STomasz Zawadzki g_scsi_cb_called = 0;
8390b1bbb45SDaniel Verkamp
8400b1bbb45SDaniel Verkamp /* max transfer length plus one block (invalid) */
8410b1bbb45SDaniel Verkamp to_be64(&cdb[2], 0); /* LBA */
8420b1bbb45SDaniel Verkamp to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512 + 1); /* transfer length */
8430b1bbb45SDaniel Verkamp task.transfer_len = SPDK_WORK_BLOCK_SIZE + 512;
84456e12b00SShuhei Matsumoto task.offset = 0;
84556e12b00SShuhei Matsumoto task.length = 1 * 512;
84618dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
8470b1bbb45SDaniel Verkamp CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
8480b1bbb45SDaniel Verkamp CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
8490b1bbb45SDaniel Verkamp CU_ASSERT((task.sense_data[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST);
8500b1bbb45SDaniel Verkamp CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB);
851a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
8520b1bbb45SDaniel Verkamp
8530720ad35SDaniel Verkamp /* zero transfer length (valid) */
8540720ad35SDaniel Verkamp to_be64(&cdb[2], 0); /* LBA */
8550720ad35SDaniel Verkamp to_be32(&cdb[10], 0); /* transfer length */
8560720ad35SDaniel Verkamp task.transfer_len = 0;
85756e12b00SShuhei Matsumoto task.offset = 0;
85856e12b00SShuhei Matsumoto task.length = 0;
85918dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
8600720ad35SDaniel Verkamp CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
8610720ad35SDaniel Verkamp CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
8620720ad35SDaniel Verkamp CU_ASSERT(task.data_transferred == 0);
863a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
8640720ad35SDaniel Verkamp
8650720ad35SDaniel Verkamp /* zero transfer length past end of disk (invalid) */
8660720ad35SDaniel Verkamp to_be64(&cdb[2], g_test_bdev_num_blocks); /* LBA */
8670720ad35SDaniel Verkamp to_be32(&cdb[10], 0); /* transfer length */
8680720ad35SDaniel Verkamp task.transfer_len = 0;
86956e12b00SShuhei Matsumoto task.offset = 0;
87056e12b00SShuhei Matsumoto task.length = 0;
87118dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
8720720ad35SDaniel Verkamp CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
8730720ad35SDaniel Verkamp CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
8740720ad35SDaniel Verkamp CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
875a8656d66STomasz Zawadzki SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
8760720ad35SDaniel Verkamp
877d5471e29STomasz Zawadzki ut_put_task(&task);
8780b1bbb45SDaniel Verkamp }
8790b1bbb45SDaniel Verkamp
8806f9e81eeSTomasz Zawadzki static void
_xfer_test(bool bdev_io_pool_full)881f0ec7bc6STomasz Zawadzki _xfer_test(bool bdev_io_pool_full)
8826f9e81eeSTomasz Zawadzki {
88356e12b00SShuhei Matsumoto struct spdk_bdev bdev = { .blocklen = 512 };
8846f9e81eeSTomasz Zawadzki struct spdk_scsi_lun lun;
8856f9e81eeSTomasz Zawadzki struct spdk_scsi_task task;
8866f9e81eeSTomasz Zawadzki uint8_t cdb[16];
8876f9e81eeSTomasz Zawadzki char data[4096];
8886f9e81eeSTomasz Zawadzki int rc;
8896f9e81eeSTomasz Zawadzki
8906f9e81eeSTomasz Zawadzki lun.bdev = &bdev;
8916f9e81eeSTomasz Zawadzki
8926f9e81eeSTomasz Zawadzki /* Test block device size of 512 MiB */
8936f9e81eeSTomasz Zawadzki g_test_bdev_num_blocks = 512 * 1024 * 1024;
8946f9e81eeSTomasz Zawadzki
8956f9e81eeSTomasz Zawadzki /* Read 1 block */
8966f9e81eeSTomasz Zawadzki ut_init_task(&task);
8976f9e81eeSTomasz Zawadzki task.lun = &lun;
89817e9d38cSSeth Howell task.lun->bdev_desc = NULL;
89917e9d38cSSeth Howell task.lun->io_channel = NULL;
9006f9e81eeSTomasz Zawadzki task.cdb = cdb;
9016f9e81eeSTomasz Zawadzki memset(cdb, 0, sizeof(cdb));
9026f9e81eeSTomasz Zawadzki cdb[0] = 0x88; /* READ (16) */
9036f9e81eeSTomasz Zawadzki to_be64(&cdb[2], 0); /* LBA */
9046f9e81eeSTomasz Zawadzki to_be32(&cdb[10], 1); /* transfer length */
9056f9e81eeSTomasz Zawadzki task.transfer_len = 1 * 512;
90656e12b00SShuhei Matsumoto task.offset = 0;
90756e12b00SShuhei Matsumoto task.length = 1 * 512;
908f0ec7bc6STomasz Zawadzki g_bdev_io_pool_full = bdev_io_pool_full;
90918dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
9106f9e81eeSTomasz Zawadzki CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
9116f9e81eeSTomasz Zawadzki CU_ASSERT(task.status == 0xFF);
9126f9e81eeSTomasz Zawadzki
9136f9e81eeSTomasz Zawadzki ut_bdev_io_flush();
9146f9e81eeSTomasz Zawadzki CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
9156f9e81eeSTomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
9166f9e81eeSTomasz Zawadzki g_scsi_cb_called = 0;
9176f9e81eeSTomasz Zawadzki ut_put_task(&task);
9186f9e81eeSTomasz Zawadzki
9196f9e81eeSTomasz Zawadzki /* Write 1 block */
9206f9e81eeSTomasz Zawadzki ut_init_task(&task);
9216f9e81eeSTomasz Zawadzki task.lun = &lun;
9226f9e81eeSTomasz Zawadzki task.cdb = cdb;
9236f9e81eeSTomasz Zawadzki memset(cdb, 0, sizeof(cdb));
9246f9e81eeSTomasz Zawadzki cdb[0] = 0x8a; /* WRITE (16) */
9256f9e81eeSTomasz Zawadzki to_be64(&cdb[2], 0); /* LBA */
9266f9e81eeSTomasz Zawadzki to_be32(&cdb[10], 1); /* transfer length */
9276f9e81eeSTomasz Zawadzki task.transfer_len = 1 * 512;
92807e9a00bSShuhei Matsumoto task.offset = 0;
92907e9a00bSShuhei Matsumoto task.length = 1 * 512;
930f0ec7bc6STomasz Zawadzki g_bdev_io_pool_full = bdev_io_pool_full;
93118dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
9326f9e81eeSTomasz Zawadzki CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
9336f9e81eeSTomasz Zawadzki CU_ASSERT(task.status == 0xFF);
9346f9e81eeSTomasz Zawadzki
9356f9e81eeSTomasz Zawadzki ut_bdev_io_flush();
9366f9e81eeSTomasz Zawadzki CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
9376f9e81eeSTomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
9386f9e81eeSTomasz Zawadzki g_scsi_cb_called = 0;
9396f9e81eeSTomasz Zawadzki ut_put_task(&task);
9406f9e81eeSTomasz Zawadzki
9416f9e81eeSTomasz Zawadzki /* Unmap 5 blocks using 2 descriptors */
9426f9e81eeSTomasz Zawadzki ut_init_task(&task);
9436f9e81eeSTomasz Zawadzki task.lun = &lun;
9446f9e81eeSTomasz Zawadzki task.cdb = cdb;
9456f9e81eeSTomasz Zawadzki memset(cdb, 0, sizeof(cdb));
9466f9e81eeSTomasz Zawadzki cdb[0] = 0x42; /* UNMAP */
9476f9e81eeSTomasz Zawadzki to_be16(&data[7], 2); /* 2 parameters in list */
9486f9e81eeSTomasz Zawadzki memset(data, 0, sizeof(data));
9496f9e81eeSTomasz Zawadzki to_be16(&data[2], 32); /* 2 descriptors */
9506f9e81eeSTomasz Zawadzki to_be64(&data[8], 1); /* LBA 1 */
9516f9e81eeSTomasz Zawadzki to_be32(&data[16], 2); /* 2 blocks */
9526f9e81eeSTomasz Zawadzki to_be64(&data[24], 10); /* LBA 10 */
9536f9e81eeSTomasz Zawadzki to_be32(&data[32], 3); /* 3 blocks */
9546f9e81eeSTomasz Zawadzki spdk_scsi_task_set_data(&task, data, sizeof(data));
9556f9e81eeSTomasz Zawadzki task.status = SPDK_SCSI_STATUS_GOOD;
956f0ec7bc6STomasz Zawadzki g_bdev_io_pool_full = bdev_io_pool_full;
95718dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
9586f9e81eeSTomasz Zawadzki CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
9596f9e81eeSTomasz Zawadzki CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
9606f9e81eeSTomasz Zawadzki
9616f9e81eeSTomasz Zawadzki ut_bdev_io_flush();
9626f9e81eeSTomasz Zawadzki CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
9636f9e81eeSTomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
9646f9e81eeSTomasz Zawadzki g_scsi_cb_called = 0;
9656f9e81eeSTomasz Zawadzki ut_put_task(&task);
9666f9e81eeSTomasz Zawadzki
9676f9e81eeSTomasz Zawadzki /* Flush 1 block */
9686f9e81eeSTomasz Zawadzki ut_init_task(&task);
9696f9e81eeSTomasz Zawadzki task.lun = &lun;
9706f9e81eeSTomasz Zawadzki task.cdb = cdb;
9716f9e81eeSTomasz Zawadzki memset(cdb, 0, sizeof(cdb));
9726f9e81eeSTomasz Zawadzki cdb[0] = 0x91; /* SYNCHRONIZE CACHE (16) */
9736f9e81eeSTomasz Zawadzki to_be64(&cdb[2], 0); /* LBA */
9746f9e81eeSTomasz Zawadzki to_be32(&cdb[10], 1); /* 1 blocks */
975f0ec7bc6STomasz Zawadzki g_bdev_io_pool_full = bdev_io_pool_full;
97618dec401SShuhei Matsumoto rc = bdev_scsi_execute(&task);
9776f9e81eeSTomasz Zawadzki CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
9786f9e81eeSTomasz Zawadzki CU_ASSERT(task.status == 0xFF);
9796f9e81eeSTomasz Zawadzki
9806f9e81eeSTomasz Zawadzki ut_bdev_io_flush();
9816f9e81eeSTomasz Zawadzki CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
9826f9e81eeSTomasz Zawadzki CU_ASSERT(g_scsi_cb_called == 1);
9836f9e81eeSTomasz Zawadzki g_scsi_cb_called = 0;
984310fc0b5Syidong0635 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
985310fc0b5Syidong0635
9866f9e81eeSTomasz Zawadzki ut_put_task(&task);
9876f9e81eeSTomasz Zawadzki }
9886f9e81eeSTomasz Zawadzki
989f0ec7bc6STomasz Zawadzki static void
xfer_test(void)990f0ec7bc6STomasz Zawadzki xfer_test(void)
991f0ec7bc6STomasz Zawadzki {
992f0ec7bc6STomasz Zawadzki _xfer_test(false);
993f0ec7bc6STomasz Zawadzki _xfer_test(true);
994f0ec7bc6STomasz Zawadzki }
995f0ec7bc6STomasz Zawadzki
9968697bce7SShuhei Matsumoto static void
get_dif_ctx_test(void)9978697bce7SShuhei Matsumoto get_dif_ctx_test(void)
9988697bce7SShuhei Matsumoto {
9998697bce7SShuhei Matsumoto struct spdk_bdev bdev = {};
100084e64cc9SShuhei Matsumoto struct spdk_scsi_task task = {};
10018697bce7SShuhei Matsumoto struct spdk_dif_ctx dif_ctx = {};
10028697bce7SShuhei Matsumoto uint8_t cdb[16];
10038697bce7SShuhei Matsumoto bool ret;
10048697bce7SShuhei Matsumoto
10058697bce7SShuhei Matsumoto cdb[0] = SPDK_SBC_READ_6;
10068697bce7SShuhei Matsumoto cdb[1] = 0x12;
10078697bce7SShuhei Matsumoto cdb[2] = 0x34;
10088697bce7SShuhei Matsumoto cdb[3] = 0x50;
100984e64cc9SShuhei Matsumoto task.cdb = cdb;
101084e64cc9SShuhei Matsumoto task.offset = 0x6 * 512;
10118697bce7SShuhei Matsumoto
101218dec401SShuhei Matsumoto ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx);
10138697bce7SShuhei Matsumoto CU_ASSERT(ret == true);
101437bdd0e8SShuhei Matsumoto CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x123456);
10158697bce7SShuhei Matsumoto
10168697bce7SShuhei Matsumoto cdb[0] = SPDK_SBC_WRITE_12;
10178697bce7SShuhei Matsumoto to_be32(&cdb[2], 0x12345670);
101884e64cc9SShuhei Matsumoto task.offset = 0x8 * 512;
10198697bce7SShuhei Matsumoto
102018dec401SShuhei Matsumoto ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx);
10218697bce7SShuhei Matsumoto CU_ASSERT(ret == true);
102237bdd0e8SShuhei Matsumoto CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x12345678);
10238697bce7SShuhei Matsumoto
10248697bce7SShuhei Matsumoto cdb[0] = SPDK_SBC_WRITE_16;
10258697bce7SShuhei Matsumoto to_be64(&cdb[2], 0x0000000012345670);
102684e64cc9SShuhei Matsumoto task.offset = 0x8 * 512;
10278697bce7SShuhei Matsumoto
102818dec401SShuhei Matsumoto ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx);
10298697bce7SShuhei Matsumoto CU_ASSERT(ret == true);
103037bdd0e8SShuhei Matsumoto CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x12345678);
10318697bce7SShuhei Matsumoto }
10328697bce7SShuhei Matsumoto
103373bc324bSShuhei Matsumoto static void
unmap_split_test(void)103473bc324bSShuhei Matsumoto unmap_split_test(void)
103573bc324bSShuhei Matsumoto {
103673bc324bSShuhei Matsumoto struct spdk_bdev bdev = { .blocklen = 512 };
103773bc324bSShuhei Matsumoto struct spdk_scsi_lun lun;
103873bc324bSShuhei Matsumoto struct spdk_scsi_task task;
103973bc324bSShuhei Matsumoto uint8_t cdb[16];
104073bc324bSShuhei Matsumoto char data[4096];
104173bc324bSShuhei Matsumoto int rc;
104273bc324bSShuhei Matsumoto
104373bc324bSShuhei Matsumoto lun.bdev = &bdev;
104473bc324bSShuhei Matsumoto
104573bc324bSShuhei Matsumoto /* Test block device size of 512 MiB */
104673bc324bSShuhei Matsumoto g_test_bdev_num_blocks = 512 * 1024 * 1024;
104773bc324bSShuhei Matsumoto
1048b735c429Szhenwei pi /* Unmap 5 blocks using 6 descriptors(descriptor 2 has 0 blocks). bdev_io pool size is 2.
104973bc324bSShuhei Matsumoto * Hence, unmap should be done by 3 iterations.
1050b735c429Szhenwei pi * 1st - 2 unmaps(0, 1), 2nd - 3 unmaps(2, 3, 4), and 3rd - 1 unmap(5).
105173bc324bSShuhei Matsumoto */
105273bc324bSShuhei Matsumoto ut_init_task(&task);
105373bc324bSShuhei Matsumoto task.lun = &lun;
105473bc324bSShuhei Matsumoto task.cdb = cdb;
105573bc324bSShuhei Matsumoto memset(cdb, 0, sizeof(cdb));
105673bc324bSShuhei Matsumoto cdb[0] = 0x42; /* UNMAP */
1057b735c429Szhenwei pi to_be16(&data[7], 6); /* 6 parameters in list */
105873bc324bSShuhei Matsumoto memset(data, 0, sizeof(data));
1059b735c429Szhenwei pi to_be16(&data[2], 16 * 6); /* 6 descriptors */
106073bc324bSShuhei Matsumoto to_be64(&data[8], 1); /* LBA 1 */
106173bc324bSShuhei Matsumoto to_be32(&data[16], 2); /* 2 blocks */
106273bc324bSShuhei Matsumoto to_be64(&data[24], 5); /* LBA 5 */
106373bc324bSShuhei Matsumoto to_be32(&data[32], 3); /* 3 blocks */
106473bc324bSShuhei Matsumoto to_be64(&data[40], 10); /* LBA 10 */
1065b735c429Szhenwei pi to_be32(&data[48], 0); /* 0 block */
106673bc324bSShuhei Matsumoto to_be64(&data[56], 15); /* LBA 15 */
106773bc324bSShuhei Matsumoto to_be32(&data[64], 4); /* 4 blocks */
106873bc324bSShuhei Matsumoto to_be64(&data[72], 30); /* LBA 30 */
106973bc324bSShuhei Matsumoto to_be32(&data[80], 1); /* 1 block */
1070b735c429Szhenwei pi to_be64(&data[88], 40); /* LBA 40 */
1071b735c429Szhenwei pi to_be32(&data[96], 1); /* 1 block */
107273bc324bSShuhei Matsumoto spdk_scsi_task_set_data(&task, data, sizeof(data));
107373bc324bSShuhei Matsumoto task.status = SPDK_SCSI_STATUS_GOOD;
107473bc324bSShuhei Matsumoto
107573bc324bSShuhei Matsumoto g_bdev_io_pool_full = true;
107673bc324bSShuhei Matsumoto
107773bc324bSShuhei Matsumoto rc = bdev_scsi_execute(&task);
107873bc324bSShuhei Matsumoto CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
107973bc324bSShuhei Matsumoto CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
108073bc324bSShuhei Matsumoto CU_ASSERT(g_scsi_cb_called == 0);
108173bc324bSShuhei Matsumoto CU_ASSERT(g_outstanding_bdev_io_count == 0);
108273bc324bSShuhei Matsumoto CU_ASSERT(g_pending_bdev_io_count == 1);
108373bc324bSShuhei Matsumoto
108473bc324bSShuhei Matsumoto g_bdev_io_pool_count = 2;
108573bc324bSShuhei Matsumoto ut_bdev_io_retry();
108673bc324bSShuhei Matsumoto
1087b735c429Szhenwei pi /* descriptor 0 and 1 */
108873bc324bSShuhei Matsumoto CU_ASSERT(g_outstanding_bdev_io_count == 2);
108973bc324bSShuhei Matsumoto CU_ASSERT(g_pending_bdev_io_count == 0);
109073bc324bSShuhei Matsumoto
109173bc324bSShuhei Matsumoto g_bdev_io_pool_full = true;
109273bc324bSShuhei Matsumoto ut_bdev_io_complete();
109373bc324bSShuhei Matsumoto
109473bc324bSShuhei Matsumoto CU_ASSERT(g_outstanding_bdev_io_count == 0);
109573bc324bSShuhei Matsumoto CU_ASSERT(g_pending_bdev_io_count == 1);
109673bc324bSShuhei Matsumoto
109773bc324bSShuhei Matsumoto ut_bdev_io_retry();
109873bc324bSShuhei Matsumoto
1099*4b527a3cSJim Harris /* descriptor 2 and 3 (descriptor 2 is valid even though it is 0 blocks) */
110073bc324bSShuhei Matsumoto CU_ASSERT(g_outstanding_bdev_io_count == 2);
110173bc324bSShuhei Matsumoto CU_ASSERT(g_pending_bdev_io_count == 0);
110273bc324bSShuhei Matsumoto
1103b735c429Szhenwei pi g_bdev_io_pool_full = true;
1104b735c429Szhenwei pi ut_bdev_io_complete();
1105b735c429Szhenwei pi
1106b735c429Szhenwei pi CU_ASSERT(g_outstanding_bdev_io_count == 0);
1107b735c429Szhenwei pi CU_ASSERT(g_pending_bdev_io_count == 1);
1108b735c429Szhenwei pi
1109b735c429Szhenwei pi ut_bdev_io_retry();
1110b735c429Szhenwei pi
1111*4b527a3cSJim Harris /* descriptor 4 and 5 */
1112*4b527a3cSJim Harris CU_ASSERT(g_outstanding_bdev_io_count == 2);
1113b735c429Szhenwei pi CU_ASSERT(g_pending_bdev_io_count == 0);
1114b735c429Szhenwei pi
111573bc324bSShuhei Matsumoto ut_bdev_io_complete();
111673bc324bSShuhei Matsumoto
111773bc324bSShuhei Matsumoto CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
111873bc324bSShuhei Matsumoto CU_ASSERT(g_scsi_cb_called == 1);
111973bc324bSShuhei Matsumoto
112073bc324bSShuhei Matsumoto g_scsi_cb_called = 0;
112173bc324bSShuhei Matsumoto g_bdev_io_pool_count = -1;
112273bc324bSShuhei Matsumoto
112373bc324bSShuhei Matsumoto SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
112473bc324bSShuhei Matsumoto SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_io_wait_queue));
112573bc324bSShuhei Matsumoto
112673bc324bSShuhei Matsumoto ut_put_task(&task);
112773bc324bSShuhei Matsumoto }
112873bc324bSShuhei Matsumoto
11298b0f2ad4SDaniel Verkamp int
main(int argc,char ** argv)11308b0f2ad4SDaniel Verkamp main(int argc, char **argv)
11318b0f2ad4SDaniel Verkamp {
11328b0f2ad4SDaniel Verkamp CU_pSuite suite = NULL;
11338b0f2ad4SDaniel Verkamp unsigned int num_failures;
11348b0f2ad4SDaniel Verkamp
1135a8656d66STomasz Zawadzki TAILQ_INIT(&g_bdev_io_queue);
1136f0ec7bc6STomasz Zawadzki TAILQ_INIT(&g_io_wait_queue);
1137a8656d66STomasz Zawadzki
113878b696bcSVitaliy Mysak CU_initialize_registry();
11398b0f2ad4SDaniel Verkamp
11408b0f2ad4SDaniel Verkamp suite = CU_add_suite("translation_suite", NULL, NULL);
11418b0f2ad4SDaniel Verkamp
1142dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, mode_select_6_test);
1143dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, mode_select_6_test2);
1144dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, mode_sense_6_test);
1145dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, mode_sense_10_test);
1146dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, inquiry_evpd_test);
1147dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, inquiry_standard_test);
1148dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, inquiry_overflow_test);
1149dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, task_complete_test);
1150dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, lba_range_test);
1151dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, xfer_len_test);
1152dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, xfer_test);
1153dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, scsi_name_padding_test);
1154dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, get_dif_ctx_test);
115573bc324bSShuhei Matsumoto CU_ADD_TEST(suite, unmap_split_test);
11568b0f2ad4SDaniel Verkamp
1157ea941caeSKonrad Sztyber num_failures = spdk_ut_run_tests(argc, argv, NULL);
11588b0f2ad4SDaniel Verkamp CU_cleanup_registry();
11598b0f2ad4SDaniel Verkamp return num_failures;
11608b0f2ad4SDaniel Verkamp }
1161