4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk/stdinc.h"
36 #include "scsi/task.c"
37 #include "scsi/scsi_bdev.c"
38 #include "common/lib/test_env.c"
40 #include "spdk_cunit.h"
42 #include "spdk_internal/mock.h"
44 SPDK_LOG_REGISTER_COMPONENT("scsi", SPDK_LOG_SCSI
)
46 struct spdk_scsi_globals g_spdk_scsi
;
48 static uint64_t g_test_bdev_num_blocks
;
50 TAILQ_HEAD(, spdk_bdev_io
) g_bdev_io_queue
;
51 int g_scsi_cb_called
= 0;
53 TAILQ_HEAD(, spdk_bdev_io_wait_entry
) g_io_wait_queue
;
54 bool g_bdev_io_pool_full
= false;
57 spdk_bdev_io_type_supported(struct spdk_bdev
*bdev
, enum spdk_bdev_io_type io_type
)
63 DEFINE_STUB_V(spdk_bdev_free_io
, (struct spdk_bdev_io
*bdev_io
));
65 DEFINE_STUB(spdk_bdev_get_name
, const char *,
66 (const struct spdk_bdev
*bdev
), "test");
68 DEFINE_STUB(spdk_bdev_get_block_size
, uint32_t,
69 (const struct spdk_bdev
*bdev
), 512);
71 DEFINE_STUB(spdk_bdev_get_md_size
, uint32_t,
72 (const struct spdk_bdev
*bdev
), 8);
74 DEFINE_STUB(spdk_bdev_is_md_interleaved
, bool,
75 (const struct spdk_bdev
*bdev
), false);
77 DEFINE_STUB(spdk_bdev_get_data_block_size
, uint32_t,
78 (const struct spdk_bdev
*bdev
), 512);
81 spdk_bdev_get_num_blocks(const struct spdk_bdev
*bdev
)
83 return g_test_bdev_num_blocks
;
86 DEFINE_STUB(spdk_bdev_get_product_name
, const char *,
87 (const struct spdk_bdev
*bdev
), "test product");
89 DEFINE_STUB(spdk_bdev_has_write_cache
, bool,
90 (const struct spdk_bdev
*bdev
), false);
92 DEFINE_STUB(spdk_bdev_get_dif_type
, enum spdk_dif_type
,
93 (const struct spdk_bdev
*bdev
), SPDK_DIF_DISABLE
);
95 DEFINE_STUB(spdk_bdev_is_dif_head_of_md
, bool,
96 (const struct spdk_bdev
*bdev
), false);
98 DEFINE_STUB(spdk_bdev_is_dif_check_enabled
, bool,
99 (const struct spdk_bdev
*bdev
, enum spdk_dif_check_type check_type
), false);
101 DEFINE_STUB(scsi_pr_out
, int, (struct spdk_scsi_task
*task
,
102 uint8_t *cdb
, uint8_t *data
, uint16_t data_len
), 0);
104 DEFINE_STUB(scsi_pr_in
, int, (struct spdk_scsi_task
*task
, uint8_t *cdb
,
105 uint8_t *data
, uint16_t data_len
), 0);
107 DEFINE_STUB(scsi2_reserve
, int, (struct spdk_scsi_task
*task
, uint8_t *cdb
), 0);
108 DEFINE_STUB(scsi2_release
, int, (struct spdk_scsi_task
*task
), 0);
111 scsi_lun_complete_task(struct spdk_scsi_lun
*lun
, struct spdk_scsi_task
*task
)
116 DEFINE_STUB_V(scsi_lun_complete_reset_task
,
117 (struct spdk_scsi_lun
*lun
, struct spdk_scsi_task
*task
));
119 DEFINE_STUB(spdk_scsi_lun_id_int_to_fmt
, uint64_t, (int lun_id
), 0);
122 ut_put_task(struct spdk_scsi_task
*task
)
124 if (task
->alloc_len
) {
125 free(task
->iov
.iov_base
);
128 task
->iov
.iov_base
= NULL
;
129 task
->iov
.iov_len
= 0;
131 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue
));
135 ut_init_task(struct spdk_scsi_task
*task
)
137 memset(task
, 0xFF, sizeof(*task
));
138 task
->iov
.iov_base
= NULL
;
139 task
->iovs
= &task
->iov
;
142 task
->dxfer_dir
= SPDK_SCSI_DIR_NONE
;
146 spdk_bdev_io_get_scsi_status(const struct spdk_bdev_io
*bdev_io
,
147 int *sc
, int *sk
, int *asc
, int *ascq
)
149 switch (bdev_io
->internal
.status
) {
150 case SPDK_BDEV_IO_STATUS_SUCCESS
:
151 *sc
= SPDK_SCSI_STATUS_GOOD
;
152 *sk
= SPDK_SCSI_SENSE_NO_SENSE
;
153 *asc
= SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE
;
154 *ascq
= SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE
;
156 case SPDK_BDEV_IO_STATUS_SCSI_ERROR
:
157 *sc
= bdev_io
->internal
.error
.scsi
.sc
;
158 *sk
= bdev_io
->internal
.error
.scsi
.sk
;
159 *asc
= bdev_io
->internal
.error
.scsi
.asc
;
160 *ascq
= bdev_io
->internal
.error
.scsi
.ascq
;
163 *sc
= SPDK_SCSI_STATUS_CHECK_CONDITION
;
164 *sk
= SPDK_SCSI_SENSE_ABORTED_COMMAND
;
165 *asc
= SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE
;
166 *ascq
= SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE
;
172 spdk_bdev_io_get_iovec(struct spdk_bdev_io
*bdev_io
, struct iovec
**iovp
, int *iovcntp
)
179 ut_bdev_io_flush(void)
181 struct spdk_bdev_io
*bdev_io
;
182 struct spdk_bdev_io_wait_entry
*entry
;
184 while (!TAILQ_EMPTY(&g_bdev_io_queue
) || !TAILQ_EMPTY(&g_io_wait_queue
)) {
185 while (!TAILQ_EMPTY(&g_bdev_io_queue
)) {
186 bdev_io
= TAILQ_FIRST(&g_bdev_io_queue
);
187 TAILQ_REMOVE(&g_bdev_io_queue
, bdev_io
, internal
.link
);
188 bdev_io
->internal
.cb(bdev_io
, true, bdev_io
->internal
.caller_ctx
);
192 while (!TAILQ_EMPTY(&g_io_wait_queue
)) {
193 entry
= TAILQ_FIRST(&g_io_wait_queue
);
194 TAILQ_REMOVE(&g_io_wait_queue
, entry
, link
);
195 entry
->cb_fn(entry
->cb_arg
);
201 _spdk_bdev_io_op(spdk_bdev_io_completion_cb cb
, void *cb_arg
)
203 struct spdk_bdev_io
*bdev_io
;
205 if (g_bdev_io_pool_full
) {
206 g_bdev_io_pool_full
= false;
210 bdev_io
= calloc(1, sizeof(*bdev_io
));
211 SPDK_CU_ASSERT_FATAL(bdev_io
!= NULL
);
212 bdev_io
->internal
.status
= SPDK_BDEV_IO_STATUS_SUCCESS
;
213 bdev_io
->internal
.cb
= cb
;
214 bdev_io
->internal
.caller_ctx
= cb_arg
;
216 TAILQ_INSERT_TAIL(&g_bdev_io_queue
, bdev_io
, internal
.link
);
222 spdk_bdev_readv_blocks(struct spdk_bdev_desc
*desc
, struct spdk_io_channel
*ch
,
223 struct iovec
*iov
, int iovcnt
,
224 uint64_t offset_blocks
, uint64_t num_blocks
,
225 spdk_bdev_io_completion_cb cb
, void *cb_arg
)
227 return _spdk_bdev_io_op(cb
, cb_arg
);
231 spdk_bdev_writev_blocks(struct spdk_bdev_desc
*desc
, struct spdk_io_channel
*ch
,
232 struct iovec
*iov
, int iovcnt
,
233 uint64_t offset_blocks
, uint64_t num_blocks
,
234 spdk_bdev_io_completion_cb cb
, void *cb_arg
)
236 return _spdk_bdev_io_op(cb
, cb_arg
);
240 spdk_bdev_unmap_blocks(struct spdk_bdev_desc
*desc
, struct spdk_io_channel
*ch
,
241 uint64_t offset_blocks
, uint64_t num_blocks
,
242 spdk_bdev_io_completion_cb cb
, void *cb_arg
)
244 return _spdk_bdev_io_op(cb
, cb_arg
);
248 spdk_bdev_reset(struct spdk_bdev_desc
*desc
, struct spdk_io_channel
*ch
,
249 spdk_bdev_io_completion_cb cb
, void *cb_arg
)
251 return _spdk_bdev_io_op(cb
, cb_arg
);
255 spdk_bdev_flush_blocks(struct spdk_bdev_desc
*desc
, struct spdk_io_channel
*ch
,
256 uint64_t offset_blocks
, uint64_t num_blocks
,
257 spdk_bdev_io_completion_cb cb
, void *cb_arg
)
259 return _spdk_bdev_io_op(cb
, cb_arg
);
263 spdk_bdev_queue_io_wait(struct spdk_bdev
*bdev
, struct spdk_io_channel
*ch
,
264 struct spdk_bdev_io_wait_entry
*entry
)
266 TAILQ_INSERT_TAIL(&g_io_wait_queue
, entry
, link
);
271 spdk_dif_ctx_init(struct spdk_dif_ctx
*ctx
, uint32_t block_size
, uint32_t md_size
,
272 bool md_interleave
, bool dif_loc
, enum spdk_dif_type dif_type
, uint32_t dif_flags
,
273 uint32_t init_ref_tag
, uint16_t apptag_mask
, uint16_t app_tag
,
274 uint32_t data_offset
, uint16_t guard_seed
)
276 ctx
->init_ref_tag
= init_ref_tag
;
277 ctx
->ref_tag_offset
= data_offset
/ 512;
282 * This test specifically tests a mode select 6 command from the
283 * Windows SCSI compliance test that caused SPDK to crash.
286 mode_select_6_test(void)
288 struct spdk_bdev bdev
;
289 struct spdk_scsi_task task
;
290 struct spdk_scsi_lun lun
;
291 struct spdk_scsi_dev dev
;
306 snprintf(&dev
.name
[0], sizeof(dev
.name
), "spdk_iscsi_translation_test");
311 memset(data
, 0, sizeof(data
));
314 spdk_scsi_task_set_data(&task
, data
, sizeof(data
));
316 rc
= bdev_scsi_execute(&task
);
318 CU_ASSERT_EQUAL(rc
, 0);
324 * This test specifically tests a mode select 6 command which
325 * contains no mode pages.
328 mode_select_6_test2(void)
330 struct spdk_bdev bdev
;
331 struct spdk_scsi_task task
;
332 struct spdk_scsi_lun lun
;
333 struct spdk_scsi_dev dev
;
347 snprintf(&dev
.name
[0], sizeof(dev
.name
), "spdk_iscsi_translation_test");
352 rc
= bdev_scsi_execute(&task
);
354 CU_ASSERT_EQUAL(rc
, 0);
360 * This test specifically tests a mode sense 6 command which
361 * return all subpage 00h mode pages.
364 mode_sense_6_test(void)
366 struct spdk_bdev bdev
;
367 struct spdk_scsi_task task
;
368 struct spdk_scsi_lun lun
;
369 struct spdk_scsi_dev dev
;
373 unsigned char mode_data_len
= 0;
374 unsigned char medium_type
= 0;
375 unsigned char dev_specific_param
= 0;
376 unsigned char blk_descriptor_len
= 0;
378 memset(&bdev
, 0, sizeof(struct spdk_bdev
));
380 memset(cdb
, 0, sizeof(cdb
));
387 snprintf(&dev
.name
[0], sizeof(dev
.name
), "spdk_iscsi_translation_test");
392 rc
= bdev_scsi_execute(&task
);
393 SPDK_CU_ASSERT_FATAL(rc
== 0);
395 data
= task
.iovs
[0].iov_base
;
396 mode_data_len
= data
[0];
397 medium_type
= data
[1];
398 dev_specific_param
= data
[2];
399 blk_descriptor_len
= data
[3];
401 CU_ASSERT(mode_data_len
>= 11);
402 CU_ASSERT_EQUAL(medium_type
, 0);
403 CU_ASSERT_EQUAL(dev_specific_param
, 0);
404 CU_ASSERT_EQUAL(blk_descriptor_len
, 8);
410 * This test specifically tests a mode sense 10 command which
411 * return all subpage 00h mode pages.
414 mode_sense_10_test(void)
416 struct spdk_bdev bdev
;
417 struct spdk_scsi_task task
;
418 struct spdk_scsi_lun lun
;
419 struct spdk_scsi_dev dev
;
423 unsigned short mode_data_len
= 0;
424 unsigned char medium_type
= 0;
425 unsigned char dev_specific_param
= 0;
426 unsigned short blk_descriptor_len
= 0;
428 memset(&bdev
, 0, sizeof(struct spdk_bdev
));
430 memset(cdb
, 0, sizeof(cdb
));
436 snprintf(&dev
.name
[0], sizeof(dev
.name
), "spdk_iscsi_translation_test");
441 rc
= bdev_scsi_execute(&task
);
442 SPDK_CU_ASSERT_FATAL(rc
== 0);
444 data
= task
.iovs
[0].iov_base
;
445 mode_data_len
= ((data
[0] << 8) + data
[1]);
446 medium_type
= data
[2];
447 dev_specific_param
= data
[3];
448 blk_descriptor_len
= ((data
[6] << 8) + data
[7]);
450 CU_ASSERT(mode_data_len
>= 14);
451 CU_ASSERT_EQUAL(medium_type
, 0);
452 CU_ASSERT_EQUAL(dev_specific_param
, 0);
453 CU_ASSERT_EQUAL(blk_descriptor_len
, 8);
459 * This test specifically tests a scsi inquiry command from the
460 * Windows SCSI compliance test that failed to return the
461 * expected SCSI error sense code.
464 inquiry_evpd_test(void)
466 struct spdk_bdev bdev
;
467 struct spdk_scsi_task task
;
468 struct spdk_scsi_lun lun
;
469 struct spdk_scsi_dev dev
;
476 cdb
[1] = 0x00; /* EVPD = 0 */
477 cdb
[2] = 0xff; /* PageCode non-zero */
483 snprintf(&dev
.name
[0], sizeof(dev
.name
), "spdk_iscsi_translation_test");
488 rc
= bdev_scsi_execute(&task
);
489 SPDK_CU_ASSERT_FATAL(rc
== 0);
491 CU_ASSERT_EQUAL(task
.status
, SPDK_SCSI_STATUS_CHECK_CONDITION
);
492 CU_ASSERT_EQUAL(task
.sense_data
[2] & 0xf, SPDK_SCSI_SENSE_ILLEGAL_REQUEST
);
493 CU_ASSERT_EQUAL(task
.sense_data
[12], 0x24);
494 CU_ASSERT_EQUAL(task
.sense_data
[13], 0x0);
500 * This test is to verify specific return data for a standard scsi inquiry
504 inquiry_standard_test(void)
506 struct spdk_bdev bdev
= { .blocklen
= 512 };
507 struct spdk_scsi_task task
;
508 struct spdk_scsi_lun lun
;
509 struct spdk_scsi_dev dev
;
512 struct spdk_scsi_cdb_inquiry_data
*inq_data
;
518 cdb
[1] = 0x00; /* EVPD = 0 */
519 cdb
[2] = 0x00; /* PageCode zero - requesting standard inquiry */
521 cdb
[4] = 0xff; /* Indicate data size used by conformance test */
525 snprintf(&dev
.name
[0], sizeof(dev
.name
), "spdk_iscsi_translation_test");
530 rc
= bdev_scsi_execute(&task
);
532 data
= task
.iovs
[0].iov_base
;
533 inq_data
= (struct spdk_scsi_cdb_inquiry_data
*)&data
[0];
535 CU_ASSERT_EQUAL(inq_data
->version
, SPDK_SPC_VERSION_SPC3
);
536 CU_ASSERT_EQUAL(rc
, 0);
542 _inquiry_overflow_test(uint8_t alloc_len
)
544 struct spdk_bdev bdev
= { .blocklen
= 512 };
545 struct spdk_scsi_task task
;
546 struct spdk_scsi_lun lun
;
547 struct spdk_scsi_dev dev
;
550 /* expects a 4K internal data buffer */
551 char data
[4096], data_compare
[4096];
556 cdb
[1] = 0x00; /* EVPD = 0 */
557 cdb
[2] = 0x00; /* PageCode zero - requesting standard inquiry */
559 cdb
[4] = alloc_len
; /* Indicate data size used by conformance test */
563 snprintf(&dev
.name
[0], sizeof(dev
.name
), "spdk_iscsi_translation_test");
568 memset(data
, 0, sizeof(data
));
569 memset(data_compare
, 0, sizeof(data_compare
));
571 spdk_scsi_task_set_data(&task
, data
, sizeof(data
));
573 rc
= bdev_scsi_execute(&task
);
574 SPDK_CU_ASSERT_FATAL(rc
== 0);
576 CU_ASSERT_EQUAL(memcmp(data
+ alloc_len
, data_compare
+ alloc_len
, sizeof(data
) - alloc_len
), 0);
577 CU_ASSERT(task
.data_transferred
<= alloc_len
);
583 inquiry_overflow_test(void)
587 for (i
= 0; i
< 256; i
++) {
588 _inquiry_overflow_test(i
);
593 scsi_name_padding_test(void)
595 char name
[SPDK_SCSI_DEV_MAX_NAME
+ 1];
596 char buf
[SPDK_SCSI_DEV_MAX_NAME
+ 1];
600 memset(name
, '\0', sizeof(name
));
601 memset(name
, 'x', 251);
602 written
= bdev_scsi_pad_scsi_name(buf
, name
);
604 CU_ASSERT(written
== 252);
605 CU_ASSERT(buf
[250] == 'x');
606 CU_ASSERT(buf
[251] == '\0');
609 memset(name
, '\0', sizeof(name
));
610 memset(name
, 'x', 252);
611 written
= bdev_scsi_pad_scsi_name(buf
, name
);
613 CU_ASSERT(written
== 256);
614 CU_ASSERT(buf
[251] == 'x');
615 for (i
= 252; i
< 256; i
++) {
616 CU_ASSERT(buf
[i
] == '\0');
620 memset(name
, '\0', sizeof(name
));
621 memset(name
, 'x', 255);
622 written
= bdev_scsi_pad_scsi_name(buf
, name
);
624 CU_ASSERT(written
== 256);
625 CU_ASSERT(buf
[254] == 'x');
626 CU_ASSERT(buf
[255] == '\0');
630 * This test is to verify specific error translation from bdev to scsi.
633 task_complete_test(void)
635 struct spdk_scsi_task task
;
636 struct spdk_bdev_io bdev_io
= {};
637 struct spdk_scsi_lun lun
;
641 TAILQ_INIT(&lun
.tasks
);
642 TAILQ_INSERT_TAIL(&lun
.tasks
, &task
, scsi_link
);
645 bdev_io
.internal
.status
= SPDK_BDEV_IO_STATUS_SUCCESS
;
646 bdev_scsi_task_complete_cmd(&bdev_io
, bdev_io
.internal
.status
, &task
);
647 CU_ASSERT_EQUAL(task
.status
, SPDK_SCSI_STATUS_GOOD
);
648 CU_ASSERT(g_scsi_cb_called
== 1);
649 g_scsi_cb_called
= 0;
651 bdev_io
.internal
.status
= SPDK_BDEV_IO_STATUS_SCSI_ERROR
;
652 bdev_io
.internal
.error
.scsi
.sc
= SPDK_SCSI_STATUS_CHECK_CONDITION
;
653 bdev_io
.internal
.error
.scsi
.sk
= SPDK_SCSI_SENSE_HARDWARE_ERROR
;
654 bdev_io
.internal
.error
.scsi
.asc
= SPDK_SCSI_ASC_WARNING
;
655 bdev_io
.internal
.error
.scsi
.ascq
= SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED
;
656 bdev_scsi_task_complete_cmd(&bdev_io
, bdev_io
.internal
.status
, &task
);
657 CU_ASSERT_EQUAL(task
.status
, SPDK_SCSI_STATUS_CHECK_CONDITION
);
658 CU_ASSERT_EQUAL(task
.sense_data
[2] & 0xf, SPDK_SCSI_SENSE_HARDWARE_ERROR
);
659 CU_ASSERT_EQUAL(task
.sense_data
[12], SPDK_SCSI_ASC_WARNING
);
660 CU_ASSERT_EQUAL(task
.sense_data
[13], SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED
);
661 CU_ASSERT(g_scsi_cb_called
== 1);
662 g_scsi_cb_called
= 0;
664 bdev_io
.internal
.status
= SPDK_BDEV_IO_STATUS_FAILED
;
665 bdev_scsi_task_complete_cmd(&bdev_io
, bdev_io
.internal
.status
, &task
);
666 CU_ASSERT_EQUAL(task
.status
, SPDK_SCSI_STATUS_CHECK_CONDITION
);
667 CU_ASSERT_EQUAL(task
.sense_data
[2] & 0xf, SPDK_SCSI_SENSE_ABORTED_COMMAND
);
668 CU_ASSERT_EQUAL(task
.sense_data
[12], SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE
);
669 CU_ASSERT_EQUAL(task
.sense_data
[13], SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE
);
670 CU_ASSERT(g_scsi_cb_called
== 1);
671 g_scsi_cb_called
= 0;
679 struct spdk_bdev bdev
= { .blocklen
= 512 };
680 struct spdk_scsi_lun lun
;
681 struct spdk_scsi_task task
;
689 task
.lun
->bdev_desc
= NULL
;
690 task
.lun
->io_channel
= NULL
;
693 memset(cdb
, 0, sizeof(cdb
));
694 cdb
[0] = 0x88; /* READ (16) */
696 /* Test block device size of 4 blocks */
697 g_test_bdev_num_blocks
= 4;
699 /* LBA = 0, length = 1 (in range) */
700 to_be64(&cdb
[2], 0); /* LBA */
701 to_be32(&cdb
[10], 1); /* transfer length */
702 task
.transfer_len
= 1 * 512;
704 task
.length
= 1 * 512;
705 rc
= bdev_scsi_execute(&task
);
706 CU_ASSERT(rc
== SPDK_SCSI_TASK_PENDING
);
707 CU_ASSERT(task
.status
== 0xFF);
708 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue
));
710 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_GOOD
);
711 CU_ASSERT(g_scsi_cb_called
== 1);
712 g_scsi_cb_called
= 0;
714 /* LBA = 4, length = 1 (LBA out of range) */
715 to_be64(&cdb
[2], 4); /* LBA */
716 to_be32(&cdb
[10], 1); /* transfer length */
717 task
.transfer_len
= 1 * 512;
719 task
.length
= 1 * 512;
720 rc
= bdev_scsi_execute(&task
);
721 CU_ASSERT(rc
== SPDK_SCSI_TASK_COMPLETE
);
722 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_CHECK_CONDITION
);
723 CU_ASSERT(task
.sense_data
[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE
);
724 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue
));
726 /* LBA = 0, length = 4 (in range, max valid size) */
727 to_be64(&cdb
[2], 0); /* LBA */
728 to_be32(&cdb
[10], 4); /* transfer length */
729 task
.transfer_len
= 4 * 512;
732 task
.length
= 1 * 512;
733 rc
= bdev_scsi_execute(&task
);
734 CU_ASSERT(rc
== SPDK_SCSI_TASK_PENDING
);
735 CU_ASSERT(task
.status
== 0xFF);
736 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue
));
738 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_GOOD
);
739 CU_ASSERT(g_scsi_cb_called
== 1);
740 g_scsi_cb_called
= 0;
742 /* LBA = 0, length = 5 (LBA in range, length beyond end of bdev) */
743 to_be64(&cdb
[2], 0); /* LBA */
744 to_be32(&cdb
[10], 5); /* transfer length */
745 task
.transfer_len
= 5 * 512;
747 task
.length
= 1 * 512;
748 rc
= bdev_scsi_execute(&task
);
749 CU_ASSERT(rc
== SPDK_SCSI_TASK_COMPLETE
);
750 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_CHECK_CONDITION
);
751 CU_ASSERT(task
.sense_data
[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE
);
752 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue
));
760 struct spdk_bdev bdev
= { .blocklen
= 512 };
761 struct spdk_scsi_lun lun
;
762 struct spdk_scsi_task task
;
770 task
.lun
->bdev_desc
= NULL
;
771 task
.lun
->io_channel
= NULL
;
774 memset(cdb
, 0, sizeof(cdb
));
775 cdb
[0] = 0x88; /* READ (16) */
777 /* Test block device size of 512 MiB */
778 g_test_bdev_num_blocks
= 512 * 1024 * 1024;
781 to_be64(&cdb
[2], 0); /* LBA */
782 to_be32(&cdb
[10], 1); /* transfer length */
783 task
.transfer_len
= 1 * 512;
785 task
.length
= 1 * 512;
786 rc
= bdev_scsi_execute(&task
);
787 CU_ASSERT(rc
== SPDK_SCSI_TASK_PENDING
);
788 CU_ASSERT(task
.status
== 0xFF);
789 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue
));
791 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_GOOD
);
792 CU_ASSERT(g_scsi_cb_called
== 1);
793 g_scsi_cb_called
= 0;
795 /* max transfer length (as reported in block limits VPD page) */
796 to_be64(&cdb
[2], 0); /* LBA */
797 to_be32(&cdb
[10], SPDK_WORK_BLOCK_SIZE
/ 512); /* transfer length */
798 task
.transfer_len
= SPDK_WORK_BLOCK_SIZE
;
801 task
.length
= 1 * 512;
802 rc
= bdev_scsi_execute(&task
);
803 CU_ASSERT(rc
== SPDK_SCSI_TASK_PENDING
);
804 CU_ASSERT(task
.status
== 0xFF);
805 SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue
));
807 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_GOOD
);
808 CU_ASSERT(g_scsi_cb_called
== 1);
809 g_scsi_cb_called
= 0;
811 /* max transfer length plus one block (invalid) */
812 to_be64(&cdb
[2], 0); /* LBA */
813 to_be32(&cdb
[10], SPDK_WORK_BLOCK_SIZE
/ 512 + 1); /* transfer length */
814 task
.transfer_len
= SPDK_WORK_BLOCK_SIZE
+ 512;
816 task
.length
= 1 * 512;
817 rc
= bdev_scsi_execute(&task
);
818 CU_ASSERT(rc
== SPDK_SCSI_TASK_COMPLETE
);
819 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_CHECK_CONDITION
);
820 CU_ASSERT((task
.sense_data
[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST
);
821 CU_ASSERT(task
.sense_data
[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB
);
822 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue
));
824 /* zero transfer length (valid) */
825 to_be64(&cdb
[2], 0); /* LBA */
826 to_be32(&cdb
[10], 0); /* transfer length */
827 task
.transfer_len
= 0;
830 rc
= bdev_scsi_execute(&task
);
831 CU_ASSERT(rc
== SPDK_SCSI_TASK_COMPLETE
);
832 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_GOOD
);
833 CU_ASSERT(task
.data_transferred
== 0);
834 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue
));
836 /* zero transfer length past end of disk (invalid) */
837 to_be64(&cdb
[2], g_test_bdev_num_blocks
); /* LBA */
838 to_be32(&cdb
[10], 0); /* transfer length */
839 task
.transfer_len
= 0;
842 rc
= bdev_scsi_execute(&task
);
843 CU_ASSERT(rc
== SPDK_SCSI_TASK_COMPLETE
);
844 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_CHECK_CONDITION
);
845 CU_ASSERT(task
.sense_data
[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE
);
846 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue
));
852 _xfer_test(bool bdev_io_pool_full
)
854 struct spdk_bdev bdev
= { .blocklen
= 512 };
855 struct spdk_scsi_lun lun
;
856 struct spdk_scsi_task task
;
863 /* Test block device size of 512 MiB */
864 g_test_bdev_num_blocks
= 512 * 1024 * 1024;
869 task
.lun
->bdev_desc
= NULL
;
870 task
.lun
->io_channel
= NULL
;
872 memset(cdb
, 0, sizeof(cdb
));
873 cdb
[0] = 0x88; /* READ (16) */
874 to_be64(&cdb
[2], 0); /* LBA */
875 to_be32(&cdb
[10], 1); /* transfer length */
876 task
.transfer_len
= 1 * 512;
878 task
.length
= 1 * 512;
879 g_bdev_io_pool_full
= bdev_io_pool_full
;
880 rc
= bdev_scsi_execute(&task
);
881 CU_ASSERT(rc
== SPDK_SCSI_TASK_PENDING
);
882 CU_ASSERT(task
.status
== 0xFF);
885 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_GOOD
);
886 CU_ASSERT(g_scsi_cb_called
== 1);
887 g_scsi_cb_called
= 0;
894 memset(cdb
, 0, sizeof(cdb
));
895 cdb
[0] = 0x8a; /* WRITE (16) */
896 to_be64(&cdb
[2], 0); /* LBA */
897 to_be32(&cdb
[10], 1); /* transfer length */
898 task
.transfer_len
= 1 * 512;
900 task
.length
= 1 * 512;
901 g_bdev_io_pool_full
= bdev_io_pool_full
;
902 rc
= bdev_scsi_execute(&task
);
903 CU_ASSERT(rc
== SPDK_SCSI_TASK_PENDING
);
904 CU_ASSERT(task
.status
== 0xFF);
907 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_GOOD
);
908 CU_ASSERT(g_scsi_cb_called
== 1);
909 g_scsi_cb_called
= 0;
912 /* Unmap 5 blocks using 2 descriptors */
916 memset(cdb
, 0, sizeof(cdb
));
917 cdb
[0] = 0x42; /* UNMAP */
918 to_be16(&data
[7], 2); /* 2 parameters in list */
919 memset(data
, 0, sizeof(data
));
920 to_be16(&data
[2], 32); /* 2 descriptors */
921 to_be64(&data
[8], 1); /* LBA 1 */
922 to_be32(&data
[16], 2); /* 2 blocks */
923 to_be64(&data
[24], 10); /* LBA 10 */
924 to_be32(&data
[32], 3); /* 3 blocks */
925 spdk_scsi_task_set_data(&task
, data
, sizeof(data
));
926 task
.status
= SPDK_SCSI_STATUS_GOOD
;
927 g_bdev_io_pool_full
= bdev_io_pool_full
;
928 rc
= bdev_scsi_execute(&task
);
929 CU_ASSERT(rc
== SPDK_SCSI_TASK_PENDING
);
930 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_GOOD
);
933 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_GOOD
);
934 CU_ASSERT(g_scsi_cb_called
== 1);
935 g_scsi_cb_called
= 0;
942 memset(cdb
, 0, sizeof(cdb
));
943 cdb
[0] = 0x91; /* SYNCHRONIZE CACHE (16) */
944 to_be64(&cdb
[2], 0); /* LBA */
945 to_be32(&cdb
[10], 1); /* 1 blocks */
946 g_bdev_io_pool_full
= bdev_io_pool_full
;
947 rc
= bdev_scsi_execute(&task
);
948 CU_ASSERT(rc
== SPDK_SCSI_TASK_PENDING
);
949 CU_ASSERT(task
.status
== 0xFF);
952 CU_ASSERT(task
.status
== SPDK_SCSI_STATUS_GOOD
);
953 CU_ASSERT(g_scsi_cb_called
== 1);
954 g_scsi_cb_called
= 0;
955 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue
));
968 get_dif_ctx_test(void)
970 struct spdk_bdev bdev
= {};
971 struct spdk_scsi_task task
= {};
972 struct spdk_dif_ctx dif_ctx
= {};
976 cdb
[0] = SPDK_SBC_READ_6
;
981 task
.offset
= 0x6 * 512;
983 ret
= bdev_scsi_get_dif_ctx(&bdev
, &task
, &dif_ctx
);
984 CU_ASSERT(ret
== true);
985 CU_ASSERT(dif_ctx
.init_ref_tag
+ dif_ctx
.ref_tag_offset
== 0x123456);
987 cdb
[0] = SPDK_SBC_WRITE_12
;
988 to_be32(&cdb
[2], 0x12345670);
989 task
.offset
= 0x8 * 512;
991 ret
= bdev_scsi_get_dif_ctx(&bdev
, &task
, &dif_ctx
);
992 CU_ASSERT(ret
== true);
993 CU_ASSERT(dif_ctx
.init_ref_tag
+ dif_ctx
.ref_tag_offset
== 0x12345678);
995 cdb
[0] = SPDK_SBC_WRITE_16
;
996 to_be64(&cdb
[2], 0x0000000012345670);
997 task
.offset
= 0x8 * 512;
999 ret
= bdev_scsi_get_dif_ctx(&bdev
, &task
, &dif_ctx
);
1000 CU_ASSERT(ret
== true);
1001 CU_ASSERT(dif_ctx
.init_ref_tag
+ dif_ctx
.ref_tag_offset
== 0x12345678);
1005 main(int argc
, char **argv
)
1007 CU_pSuite suite
= NULL
;
1008 unsigned int num_failures
;
1010 TAILQ_INIT(&g_bdev_io_queue
);
1011 TAILQ_INIT(&g_io_wait_queue
);
1013 CU_set_error_action(CUEA_ABORT
);
1014 CU_initialize_registry();
1016 suite
= CU_add_suite("translation_suite", NULL
, NULL
);
1018 CU_ADD_TEST(suite
, mode_select_6_test
);
1019 CU_ADD_TEST(suite
, mode_select_6_test2
);
1020 CU_ADD_TEST(suite
, mode_sense_6_test
);
1021 CU_ADD_TEST(suite
, mode_sense_10_test
);
1022 CU_ADD_TEST(suite
, inquiry_evpd_test
);
1023 CU_ADD_TEST(suite
, inquiry_standard_test
);
1024 CU_ADD_TEST(suite
, inquiry_overflow_test
);
1025 CU_ADD_TEST(suite
, task_complete_test
);
1026 CU_ADD_TEST(suite
, lba_range_test
);
1027 CU_ADD_TEST(suite
, xfer_len_test
);
1028 CU_ADD_TEST(suite
, xfer_test
);
1029 CU_ADD_TEST(suite
, scsi_name_padding_test
);
1030 CU_ADD_TEST(suite
, get_dif_ctx_test
);
1032 CU_basic_set_mode(CU_BRM_VERBOSE
);
1033 CU_basic_run_tests();
1034 num_failures
= CU_get_number_of_failures();
1035 CU_cleanup_registry();
1036 return num_failures
;