xref: /spdk/test/unit/lib/scsi/scsi_bdev.c/scsi_bdev_ut.c (revision 78ecd30d8e4650007c80a053011116b85f3f17ae)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
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
16  *       distribution.
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.
20  *
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.
32  */
33 
34 #include "spdk/stdinc.h"
35 
36 #include "scsi/task.c"
37 #include "scsi/scsi_bdev.c"
38 #include "common/lib/test_env.c"
39 
40 #include "spdk_cunit.h"
41 
42 #include "spdk_internal/mock.h"
43 #include "spdk/bdev_module.h"
44 
45 SPDK_LOG_REGISTER_COMPONENT(scsi)
46 
47 static uint64_t g_test_bdev_num_blocks;
48 
49 TAILQ_HEAD(, spdk_bdev_io) g_bdev_io_queue;
50 int g_scsi_cb_called = 0;
51 
52 TAILQ_HEAD(, spdk_bdev_io_wait_entry) g_io_wait_queue;
53 bool g_bdev_io_pool_full = false;
54 
55 bool
56 spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type)
57 {
58 	abort();
59 	return false;
60 }
61 
62 DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io));
63 
64 DEFINE_STUB(spdk_bdev_get_name, const char *,
65 	    (const struct spdk_bdev *bdev), "test");
66 
67 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t,
68 	    (const struct spdk_bdev *bdev), 512);
69 
70 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t,
71 	    (const struct spdk_bdev *bdev), 8);
72 
73 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool,
74 	    (const struct spdk_bdev *bdev), false);
75 
76 DEFINE_STUB(spdk_bdev_get_data_block_size, uint32_t,
77 	    (const struct spdk_bdev *bdev), 512);
78 
79 DEFINE_STUB(spdk_bdev_get_physical_block_size, uint32_t,
80 	    (const struct spdk_bdev *bdev), 4096);
81 
82 uint64_t
83 spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev)
84 {
85 	return g_test_bdev_num_blocks;
86 }
87 
88 DEFINE_STUB(spdk_bdev_get_product_name, const char *,
89 	    (const struct spdk_bdev *bdev), "test product");
90 
91 DEFINE_STUB(spdk_bdev_has_write_cache, bool,
92 	    (const struct spdk_bdev *bdev), false);
93 
94 DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type,
95 	    (const struct spdk_bdev *bdev), SPDK_DIF_DISABLE);
96 
97 DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool,
98 	    (const struct spdk_bdev *bdev), false);
99 
100 DEFINE_STUB(spdk_bdev_is_dif_check_enabled, bool,
101 	    (const struct spdk_bdev *bdev, enum spdk_dif_check_type check_type), false);
102 
103 DEFINE_STUB(scsi_pr_out, int, (struct spdk_scsi_task *task,
104 			       uint8_t *cdb, uint8_t *data, uint16_t data_len), 0);
105 
106 DEFINE_STUB(scsi_pr_in, int, (struct spdk_scsi_task *task, uint8_t *cdb,
107 			      uint8_t *data, uint16_t data_len), 0);
108 
109 DEFINE_STUB(scsi2_reserve, int, (struct spdk_scsi_task *task, uint8_t *cdb), 0);
110 DEFINE_STUB(scsi2_release, int, (struct spdk_scsi_task *task), 0);
111 
112 void
113 scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)
114 {
115 	g_scsi_cb_called++;
116 }
117 
118 DEFINE_STUB_V(scsi_lun_complete_reset_task,
119 	      (struct spdk_scsi_lun *lun, struct spdk_scsi_task *task));
120 
121 DEFINE_STUB(spdk_scsi_lun_id_int_to_fmt, uint64_t, (int lun_id), 0);
122 
123 static void
124 ut_put_task(struct spdk_scsi_task *task)
125 {
126 	if (task->alloc_len) {
127 		free(task->iov.iov_base);
128 	}
129 
130 	task->iov.iov_base = NULL;
131 	task->iov.iov_len = 0;
132 	task->alloc_len = 0;
133 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
134 }
135 
136 static void
137 ut_init_task(struct spdk_scsi_task *task)
138 {
139 	memset(task, 0xFF, sizeof(*task));
140 	task->iov.iov_base = NULL;
141 	task->iovs = &task->iov;
142 	task->iovcnt = 1;
143 	task->alloc_len = 0;
144 	task->dxfer_dir = SPDK_SCSI_DIR_NONE;
145 }
146 
147 void
148 spdk_bdev_io_get_scsi_status(const struct spdk_bdev_io *bdev_io,
149 			     int *sc, int *sk, int *asc, int *ascq)
150 {
151 	switch (bdev_io->internal.status) {
152 	case SPDK_BDEV_IO_STATUS_SUCCESS:
153 		*sc = SPDK_SCSI_STATUS_GOOD;
154 		*sk = SPDK_SCSI_SENSE_NO_SENSE;
155 		*asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
156 		*ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
157 		break;
158 	case SPDK_BDEV_IO_STATUS_SCSI_ERROR:
159 		*sc = bdev_io->internal.error.scsi.sc;
160 		*sk = bdev_io->internal.error.scsi.sk;
161 		*asc = bdev_io->internal.error.scsi.asc;
162 		*ascq = bdev_io->internal.error.scsi.ascq;
163 		break;
164 	default:
165 		*sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
166 		*sk = SPDK_SCSI_SENSE_ABORTED_COMMAND;
167 		*asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
168 		*ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
169 		break;
170 	}
171 }
172 
173 void
174 spdk_bdev_io_get_iovec(struct spdk_bdev_io *bdev_io, struct iovec **iovp, int *iovcntp)
175 {
176 	*iovp = NULL;
177 	*iovcntp = 0;
178 }
179 
180 static void
181 ut_bdev_io_flush(void)
182 {
183 	struct spdk_bdev_io *bdev_io;
184 	struct spdk_bdev_io_wait_entry *entry;
185 
186 	while (!TAILQ_EMPTY(&g_bdev_io_queue) || !TAILQ_EMPTY(&g_io_wait_queue)) {
187 		while (!TAILQ_EMPTY(&g_bdev_io_queue)) {
188 			bdev_io = TAILQ_FIRST(&g_bdev_io_queue);
189 			TAILQ_REMOVE(&g_bdev_io_queue, bdev_io, internal.link);
190 			bdev_io->internal.cb(bdev_io, true, bdev_io->internal.caller_ctx);
191 			free(bdev_io);
192 		}
193 
194 		while (!TAILQ_EMPTY(&g_io_wait_queue)) {
195 			entry = TAILQ_FIRST(&g_io_wait_queue);
196 			TAILQ_REMOVE(&g_io_wait_queue, entry, link);
197 			entry->cb_fn(entry->cb_arg);
198 		}
199 	}
200 }
201 
202 static int
203 _spdk_bdev_io_op(spdk_bdev_io_completion_cb cb, void *cb_arg)
204 {
205 	struct spdk_bdev_io *bdev_io;
206 
207 	if (g_bdev_io_pool_full) {
208 		g_bdev_io_pool_full = false;
209 		return -ENOMEM;
210 	}
211 
212 	bdev_io = calloc(1, sizeof(*bdev_io));
213 	SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
214 	bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
215 	bdev_io->internal.cb = cb;
216 	bdev_io->internal.caller_ctx = cb_arg;
217 
218 	TAILQ_INSERT_TAIL(&g_bdev_io_queue, bdev_io, internal.link);
219 
220 	return 0;
221 }
222 
223 int
224 spdk_bdev_readv_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
225 		       struct iovec *iov, int iovcnt,
226 		       uint64_t offset_blocks, uint64_t num_blocks,
227 		       spdk_bdev_io_completion_cb cb, void *cb_arg)
228 {
229 	return _spdk_bdev_io_op(cb, cb_arg);
230 }
231 
232 int
233 spdk_bdev_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
234 			struct iovec *iov, int iovcnt,
235 			uint64_t offset_blocks, uint64_t num_blocks,
236 			spdk_bdev_io_completion_cb cb, void *cb_arg)
237 {
238 	return _spdk_bdev_io_op(cb, cb_arg);
239 }
240 
241 int
242 spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
243 		       uint64_t offset_blocks, uint64_t num_blocks,
244 		       spdk_bdev_io_completion_cb cb, void *cb_arg)
245 {
246 	return _spdk_bdev_io_op(cb, cb_arg);
247 }
248 
249 int
250 spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
251 		spdk_bdev_io_completion_cb cb, void *cb_arg)
252 {
253 	return _spdk_bdev_io_op(cb, cb_arg);
254 }
255 
256 int
257 spdk_bdev_flush_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
258 		       uint64_t offset_blocks, uint64_t num_blocks,
259 		       spdk_bdev_io_completion_cb cb, void *cb_arg)
260 {
261 	return _spdk_bdev_io_op(cb, cb_arg);
262 }
263 
264 int
265 spdk_bdev_queue_io_wait(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
266 			struct spdk_bdev_io_wait_entry *entry)
267 {
268 	TAILQ_INSERT_TAIL(&g_io_wait_queue, entry, link);
269 	return 0;
270 }
271 
272 int
273 spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size,
274 		  bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
275 		  uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag,
276 		  uint32_t data_offset, uint16_t guard_seed)
277 {
278 	ctx->init_ref_tag = init_ref_tag;
279 	ctx->ref_tag_offset = data_offset / 512;
280 	return 0;
281 }
282 
283 /*
284  * This test specifically tests a mode select 6 command from the
285  *  Windows SCSI compliance test that caused SPDK to crash.
286  */
287 static void
288 mode_select_6_test(void)
289 {
290 	struct spdk_bdev bdev;
291 	struct spdk_scsi_task task;
292 	struct spdk_scsi_lun lun;
293 	struct spdk_scsi_dev dev;
294 	char cdb[16];
295 	char data[24];
296 	int rc;
297 
298 	ut_init_task(&task);
299 
300 	cdb[0] = 0x15;
301 	cdb[1] = 0x11;
302 	cdb[2] = 0x00;
303 	cdb[3] = 0x00;
304 	cdb[4] = 0x18;
305 	cdb[5] = 0x00;
306 	task.cdb = cdb;
307 
308 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
309 	lun.bdev = &bdev;
310 	lun.dev = &dev;
311 	task.lun = &lun;
312 
313 	memset(data, 0, sizeof(data));
314 	data[4] = 0x08;
315 	data[5] = 0x02;
316 	spdk_scsi_task_set_data(&task, data, sizeof(data));
317 
318 	rc = bdev_scsi_execute(&task);
319 
320 	CU_ASSERT_EQUAL(rc, 0);
321 
322 	ut_put_task(&task);
323 }
324 
325 /*
326  * This test specifically tests a mode select 6 command which
327  *  contains no mode pages.
328  */
329 static void
330 mode_select_6_test2(void)
331 {
332 	struct spdk_bdev bdev;
333 	struct spdk_scsi_task task;
334 	struct spdk_scsi_lun lun;
335 	struct spdk_scsi_dev dev;
336 	char cdb[16];
337 	int rc;
338 
339 	ut_init_task(&task);
340 
341 	cdb[0] = 0x15;
342 	cdb[1] = 0x00;
343 	cdb[2] = 0x00;
344 	cdb[3] = 0x00;
345 	cdb[4] = 0x00;
346 	cdb[5] = 0x00;
347 	task.cdb = cdb;
348 
349 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
350 	lun.bdev = &bdev;
351 	lun.dev = &dev;
352 	task.lun = &lun;
353 
354 	rc = bdev_scsi_execute(&task);
355 
356 	CU_ASSERT_EQUAL(rc, 0);
357 
358 	ut_put_task(&task);
359 }
360 
361 /*
362  * This test specifically tests a mode sense 6 command which
363  *  return all subpage 00h mode pages.
364  */
365 static void
366 mode_sense_6_test(void)
367 {
368 	struct spdk_bdev bdev;
369 	struct spdk_scsi_task task;
370 	struct spdk_scsi_lun lun;
371 	struct spdk_scsi_dev dev;
372 	char cdb[12];
373 	unsigned char *data;
374 	int rc;
375 	unsigned char mode_data_len = 0;
376 	unsigned char medium_type = 0;
377 	unsigned char dev_specific_param = 0;
378 	unsigned char blk_descriptor_len = 0;
379 
380 	memset(&bdev, 0, sizeof(struct spdk_bdev));
381 	ut_init_task(&task);
382 	memset(cdb, 0, sizeof(cdb));
383 
384 	cdb[0] = 0x1A;
385 	cdb[2] = 0x3F;
386 	cdb[4] = 0xFF;
387 	task.cdb = cdb;
388 
389 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
390 	lun.bdev = &bdev;
391 	lun.dev = &dev;
392 	task.lun = &lun;
393 
394 	rc = bdev_scsi_execute(&task);
395 	SPDK_CU_ASSERT_FATAL(rc == 0);
396 
397 	data = task.iovs[0].iov_base;
398 	mode_data_len = data[0];
399 	medium_type = data[1];
400 	dev_specific_param = data[2];
401 	blk_descriptor_len = data[3];
402 
403 	CU_ASSERT(mode_data_len >= 11);
404 	CU_ASSERT_EQUAL(medium_type, 0);
405 	CU_ASSERT_EQUAL(dev_specific_param, 0);
406 	CU_ASSERT_EQUAL(blk_descriptor_len, 8);
407 
408 	ut_put_task(&task);
409 }
410 
411 /*
412  * This test specifically tests a mode sense 10 command which
413  *  return all subpage 00h mode pages.
414  */
415 static void
416 mode_sense_10_test(void)
417 {
418 	struct spdk_bdev bdev;
419 	struct spdk_scsi_task task;
420 	struct spdk_scsi_lun lun;
421 	struct spdk_scsi_dev dev;
422 	char cdb[12];
423 	unsigned char *data;
424 	int rc;
425 	unsigned short mode_data_len = 0;
426 	unsigned char medium_type = 0;
427 	unsigned char dev_specific_param = 0;
428 	unsigned short blk_descriptor_len = 0;
429 
430 	memset(&bdev, 0, sizeof(struct spdk_bdev));
431 	ut_init_task(&task);
432 	memset(cdb, 0, sizeof(cdb));
433 	cdb[0] = 0x5A;
434 	cdb[2] = 0x3F;
435 	cdb[8] = 0xFF;
436 	task.cdb = cdb;
437 
438 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
439 	lun.bdev = &bdev;
440 	lun.dev = &dev;
441 	task.lun = &lun;
442 
443 	rc = bdev_scsi_execute(&task);
444 	SPDK_CU_ASSERT_FATAL(rc == 0);
445 
446 	data = task.iovs[0].iov_base;
447 	mode_data_len = ((data[0] << 8) + data[1]);
448 	medium_type = data[2];
449 	dev_specific_param = data[3];
450 	blk_descriptor_len = ((data[6] << 8) + data[7]);
451 
452 	CU_ASSERT(mode_data_len >= 14);
453 	CU_ASSERT_EQUAL(medium_type, 0);
454 	CU_ASSERT_EQUAL(dev_specific_param, 0);
455 	CU_ASSERT_EQUAL(blk_descriptor_len, 8);
456 
457 	ut_put_task(&task);
458 }
459 
460 /*
461  * This test specifically tests a scsi inquiry command from the
462  *  Windows SCSI compliance test that failed to return the
463  *  expected SCSI error sense code.
464  */
465 static void
466 inquiry_evpd_test(void)
467 {
468 	struct spdk_bdev bdev;
469 	struct spdk_scsi_task task;
470 	struct spdk_scsi_lun lun;
471 	struct spdk_scsi_dev dev;
472 	char cdb[6];
473 	int rc;
474 
475 	ut_init_task(&task);
476 
477 	cdb[0] = 0x12;
478 	cdb[1] = 0x00;	/* EVPD = 0 */
479 	cdb[2] = 0xff;	/* PageCode non-zero */
480 	cdb[3] = 0x00;
481 	cdb[4] = 0xff;
482 	cdb[5] = 0x00;
483 	task.cdb = cdb;
484 
485 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
486 	lun.bdev = &bdev;
487 	lun.dev = &dev;
488 	task.lun = &lun;
489 
490 	rc = bdev_scsi_execute(&task);
491 	SPDK_CU_ASSERT_FATAL(rc == 0);
492 
493 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
494 	CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ILLEGAL_REQUEST);
495 	CU_ASSERT_EQUAL(task.sense_data[12], 0x24);
496 	CU_ASSERT_EQUAL(task.sense_data[13], 0x0);
497 
498 	ut_put_task(&task);
499 }
500 
501 /*
502  * This test is to verify specific return data for a standard scsi inquiry
503  *  command: Version
504  */
505 static void
506 inquiry_standard_test(void)
507 {
508 	struct spdk_bdev bdev = { .blocklen = 512 };
509 	struct spdk_scsi_task task;
510 	struct spdk_scsi_lun lun;
511 	struct spdk_scsi_dev dev;
512 	char cdb[6];
513 	char *data;
514 	struct spdk_scsi_cdb_inquiry_data *inq_data;
515 	int rc;
516 
517 	ut_init_task(&task);
518 
519 	cdb[0] = 0x12;
520 	cdb[1] = 0x00;	/* EVPD = 0 */
521 	cdb[2] = 0x00;	/* PageCode zero - requesting standard inquiry */
522 	cdb[3] = 0x00;
523 	cdb[4] = 0xff;	/* Indicate data size used by conformance test */
524 	cdb[5] = 0x00;
525 	task.cdb = cdb;
526 
527 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
528 	lun.bdev = &bdev;
529 	lun.dev = &dev;
530 	task.lun = &lun;
531 
532 	rc = bdev_scsi_execute(&task);
533 
534 	data = task.iovs[0].iov_base;
535 	inq_data = (struct spdk_scsi_cdb_inquiry_data *)&data[0];
536 
537 	CU_ASSERT_EQUAL(inq_data->version, SPDK_SPC_VERSION_SPC3);
538 	CU_ASSERT_EQUAL(rc, 0);
539 
540 	ut_put_task(&task);
541 }
542 
543 static void
544 _inquiry_overflow_test(uint8_t alloc_len)
545 {
546 	struct spdk_bdev bdev = { .blocklen = 512 };
547 	struct spdk_scsi_task task;
548 	struct spdk_scsi_lun lun;
549 	struct spdk_scsi_dev dev;
550 	uint8_t cdb[6];
551 	int rc;
552 	/* expects a 4K internal data buffer */
553 	char data[4096], data_compare[4096];
554 
555 	ut_init_task(&task);
556 
557 	cdb[0] = 0x12;
558 	cdb[1] = 0x00;		/* EVPD = 0 */
559 	cdb[2] = 0x00;		/* PageCode zero - requesting standard inquiry */
560 	cdb[3] = 0x00;
561 	cdb[4] = alloc_len;	/* Indicate data size used by conformance test */
562 	cdb[5] = 0x00;
563 	task.cdb = cdb;
564 
565 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
566 	lun.bdev = &bdev;
567 	lun.dev = &dev;
568 	task.lun = &lun;
569 
570 	memset(data, 0, sizeof(data));
571 	memset(data_compare, 0, sizeof(data_compare));
572 
573 	spdk_scsi_task_set_data(&task, data, sizeof(data));
574 
575 	rc = bdev_scsi_execute(&task);
576 	SPDK_CU_ASSERT_FATAL(rc == 0);
577 
578 	CU_ASSERT_EQUAL(memcmp(data + alloc_len, data_compare + alloc_len, sizeof(data) - alloc_len), 0);
579 	CU_ASSERT(task.data_transferred <= alloc_len);
580 
581 	ut_put_task(&task);
582 }
583 
584 static void
585 inquiry_overflow_test(void)
586 {
587 	int i;
588 
589 	for (i = 0; i < 256; i++) {
590 		_inquiry_overflow_test(i);
591 	}
592 }
593 
594 static void
595 scsi_name_padding_test(void)
596 {
597 	char name[SPDK_SCSI_DEV_MAX_NAME + 1];
598 	char buf[SPDK_SCSI_DEV_MAX_NAME + 1];
599 	int written, i;
600 
601 	/* case 1 */
602 	memset(name, '\0', sizeof(name));
603 	memset(name, 'x', 251);
604 	written = bdev_scsi_pad_scsi_name(buf, name);
605 
606 	CU_ASSERT(written == 252);
607 	CU_ASSERT(buf[250] == 'x');
608 	CU_ASSERT(buf[251] == '\0');
609 
610 	/* case 2:  */
611 	memset(name, '\0', sizeof(name));
612 	memset(name, 'x', 252);
613 	written = bdev_scsi_pad_scsi_name(buf, name);
614 
615 	CU_ASSERT(written == 256);
616 	CU_ASSERT(buf[251] == 'x');
617 	for (i = 252; i < 256; i++) {
618 		CU_ASSERT(buf[i] == '\0');
619 	}
620 
621 	/* case 3 */
622 	memset(name, '\0', sizeof(name));
623 	memset(name, 'x', 255);
624 	written = bdev_scsi_pad_scsi_name(buf, name);
625 
626 	CU_ASSERT(written == 256);
627 	CU_ASSERT(buf[254] == 'x');
628 	CU_ASSERT(buf[255] == '\0');
629 }
630 
631 /*
632  * This test is to verify specific error translation from bdev to scsi.
633  */
634 static void
635 task_complete_test(void)
636 {
637 	struct spdk_scsi_task task;
638 	struct spdk_bdev_io bdev_io = {};
639 	struct spdk_scsi_lun lun;
640 
641 	ut_init_task(&task);
642 
643 	TAILQ_INIT(&lun.tasks);
644 	TAILQ_INSERT_TAIL(&lun.tasks, &task, scsi_link);
645 	task.lun = &lun;
646 
647 	bdev_io.internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
648 	bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task);
649 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD);
650 	CU_ASSERT(g_scsi_cb_called == 1);
651 	g_scsi_cb_called = 0;
652 
653 	bdev_io.internal.status = SPDK_BDEV_IO_STATUS_SCSI_ERROR;
654 	bdev_io.internal.error.scsi.sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
655 	bdev_io.internal.error.scsi.sk = SPDK_SCSI_SENSE_HARDWARE_ERROR;
656 	bdev_io.internal.error.scsi.asc = SPDK_SCSI_ASC_WARNING;
657 	bdev_io.internal.error.scsi.ascq = SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED;
658 	bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task);
659 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
660 	CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_HARDWARE_ERROR);
661 	CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_WARNING);
662 	CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED);
663 	CU_ASSERT(g_scsi_cb_called == 1);
664 	g_scsi_cb_called = 0;
665 
666 	bdev_io.internal.status = SPDK_BDEV_IO_STATUS_FAILED;
667 	bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task);
668 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
669 	CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ABORTED_COMMAND);
670 	CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE);
671 	CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
672 	CU_ASSERT(g_scsi_cb_called == 1);
673 	g_scsi_cb_called = 0;
674 
675 	ut_put_task(&task);
676 }
677 
678 static void
679 lba_range_test(void)
680 {
681 	struct spdk_bdev bdev = { .blocklen = 512 };
682 	struct spdk_scsi_lun lun;
683 	struct spdk_scsi_task task;
684 	uint8_t cdb[16];
685 	int rc;
686 
687 	lun.bdev = &bdev;
688 
689 	ut_init_task(&task);
690 	task.lun = &lun;
691 	task.lun->bdev_desc = NULL;
692 	task.lun->io_channel = NULL;
693 	task.cdb = cdb;
694 
695 	memset(cdb, 0, sizeof(cdb));
696 	cdb[0] = 0x88; /* READ (16) */
697 
698 	/* Test block device size of 4 blocks */
699 	g_test_bdev_num_blocks = 4;
700 
701 	/* LBA = 0, length = 1 (in range) */
702 	to_be64(&cdb[2], 0); /* LBA */
703 	to_be32(&cdb[10], 1); /* transfer length */
704 	task.transfer_len = 1 * 512;
705 	task.offset = 0;
706 	task.length = 1 * 512;
707 	rc = bdev_scsi_execute(&task);
708 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
709 	CU_ASSERT(task.status == 0xFF);
710 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
711 	ut_bdev_io_flush();
712 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
713 	CU_ASSERT(g_scsi_cb_called == 1);
714 	g_scsi_cb_called = 0;
715 
716 	/* LBA = 4, length = 1 (LBA out of range) */
717 	to_be64(&cdb[2], 4); /* LBA */
718 	to_be32(&cdb[10], 1); /* transfer length */
719 	task.transfer_len = 1 * 512;
720 	task.offset = 0;
721 	task.length = 1 * 512;
722 	rc = bdev_scsi_execute(&task);
723 	CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
724 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
725 	CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
726 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
727 
728 	/* LBA = 0, length = 4 (in range, max valid size) */
729 	to_be64(&cdb[2], 0); /* LBA */
730 	to_be32(&cdb[10], 4); /* transfer length */
731 	task.transfer_len = 4 * 512;
732 	task.status = 0xFF;
733 	task.offset = 0;
734 	task.length = 1 * 512;
735 	rc = bdev_scsi_execute(&task);
736 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
737 	CU_ASSERT(task.status == 0xFF);
738 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
739 	ut_bdev_io_flush();
740 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
741 	CU_ASSERT(g_scsi_cb_called == 1);
742 	g_scsi_cb_called = 0;
743 
744 	/* LBA = 0, length = 5 (LBA in range, length beyond end of bdev) */
745 	to_be64(&cdb[2], 0); /* LBA */
746 	to_be32(&cdb[10], 5); /* transfer length */
747 	task.transfer_len = 5 * 512;
748 	task.offset = 0;
749 	task.length = 1 * 512;
750 	rc = bdev_scsi_execute(&task);
751 	CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
752 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
753 	CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
754 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
755 
756 	ut_put_task(&task);
757 }
758 
759 static void
760 xfer_len_test(void)
761 {
762 	struct spdk_bdev bdev = { .blocklen = 512 };
763 	struct spdk_scsi_lun lun;
764 	struct spdk_scsi_task task;
765 	uint8_t cdb[16];
766 	int rc;
767 
768 	lun.bdev = &bdev;
769 
770 	ut_init_task(&task);
771 	task.lun = &lun;
772 	task.lun->bdev_desc = NULL;
773 	task.lun->io_channel = NULL;
774 	task.cdb = cdb;
775 
776 	memset(cdb, 0, sizeof(cdb));
777 	cdb[0] = 0x88; /* READ (16) */
778 
779 	/* Test block device size of 512 MiB */
780 	g_test_bdev_num_blocks = 512 * 1024 * 1024;
781 
782 	/* 1 block */
783 	to_be64(&cdb[2], 0); /* LBA */
784 	to_be32(&cdb[10], 1); /* transfer length */
785 	task.transfer_len = 1 * 512;
786 	task.offset = 0;
787 	task.length = 1 * 512;
788 	rc = bdev_scsi_execute(&task);
789 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
790 	CU_ASSERT(task.status == 0xFF);
791 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
792 	ut_bdev_io_flush();
793 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
794 	CU_ASSERT(g_scsi_cb_called == 1);
795 	g_scsi_cb_called = 0;
796 
797 	/* max transfer length (as reported in block limits VPD page) */
798 	to_be64(&cdb[2], 0); /* LBA */
799 	to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512); /* transfer length */
800 	task.transfer_len = SPDK_WORK_BLOCK_SIZE;
801 	task.status = 0xFF;
802 	task.offset = 0;
803 	task.length = 1 * 512;
804 	rc = bdev_scsi_execute(&task);
805 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
806 	CU_ASSERT(task.status == 0xFF);
807 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
808 	ut_bdev_io_flush();
809 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
810 	CU_ASSERT(g_scsi_cb_called == 1);
811 	g_scsi_cb_called = 0;
812 
813 	/* max transfer length plus one block (invalid) */
814 	to_be64(&cdb[2], 0); /* LBA */
815 	to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512 + 1); /* transfer length */
816 	task.transfer_len = SPDK_WORK_BLOCK_SIZE + 512;
817 	task.offset = 0;
818 	task.length = 1 * 512;
819 	rc = bdev_scsi_execute(&task);
820 	CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
821 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
822 	CU_ASSERT((task.sense_data[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST);
823 	CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB);
824 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
825 
826 	/* zero transfer length (valid) */
827 	to_be64(&cdb[2], 0); /* LBA */
828 	to_be32(&cdb[10], 0); /* transfer length */
829 	task.transfer_len = 0;
830 	task.offset = 0;
831 	task.length = 0;
832 	rc = bdev_scsi_execute(&task);
833 	CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
834 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
835 	CU_ASSERT(task.data_transferred == 0);
836 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
837 
838 	/* zero transfer length past end of disk (invalid) */
839 	to_be64(&cdb[2], g_test_bdev_num_blocks); /* LBA */
840 	to_be32(&cdb[10], 0); /* transfer length */
841 	task.transfer_len = 0;
842 	task.offset = 0;
843 	task.length = 0;
844 	rc = bdev_scsi_execute(&task);
845 	CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
846 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
847 	CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
848 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
849 
850 	ut_put_task(&task);
851 }
852 
853 static void
854 _xfer_test(bool bdev_io_pool_full)
855 {
856 	struct spdk_bdev bdev = { .blocklen = 512 };
857 	struct spdk_scsi_lun lun;
858 	struct spdk_scsi_task task;
859 	uint8_t cdb[16];
860 	char data[4096];
861 	int rc;
862 
863 	lun.bdev = &bdev;
864 
865 	/* Test block device size of 512 MiB */
866 	g_test_bdev_num_blocks = 512 * 1024 * 1024;
867 
868 	/* Read 1 block */
869 	ut_init_task(&task);
870 	task.lun = &lun;
871 	task.lun->bdev_desc = NULL;
872 	task.lun->io_channel = NULL;
873 	task.cdb = cdb;
874 	memset(cdb, 0, sizeof(cdb));
875 	cdb[0] = 0x88; /* READ (16) */
876 	to_be64(&cdb[2], 0); /* LBA */
877 	to_be32(&cdb[10], 1); /* transfer length */
878 	task.transfer_len = 1 * 512;
879 	task.offset = 0;
880 	task.length = 1 * 512;
881 	g_bdev_io_pool_full = bdev_io_pool_full;
882 	rc = bdev_scsi_execute(&task);
883 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
884 	CU_ASSERT(task.status == 0xFF);
885 
886 	ut_bdev_io_flush();
887 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
888 	CU_ASSERT(g_scsi_cb_called == 1);
889 	g_scsi_cb_called = 0;
890 	ut_put_task(&task);
891 
892 	/* Write 1 block */
893 	ut_init_task(&task);
894 	task.lun = &lun;
895 	task.cdb = cdb;
896 	memset(cdb, 0, sizeof(cdb));
897 	cdb[0] = 0x8a; /* WRITE (16) */
898 	to_be64(&cdb[2], 0); /* LBA */
899 	to_be32(&cdb[10], 1); /* transfer length */
900 	task.transfer_len = 1 * 512;
901 	task.offset = 0;
902 	task.length = 1 * 512;
903 	g_bdev_io_pool_full = bdev_io_pool_full;
904 	rc = bdev_scsi_execute(&task);
905 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
906 	CU_ASSERT(task.status == 0xFF);
907 
908 	ut_bdev_io_flush();
909 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
910 	CU_ASSERT(g_scsi_cb_called == 1);
911 	g_scsi_cb_called = 0;
912 	ut_put_task(&task);
913 
914 	/* Unmap 5 blocks using 2 descriptors */
915 	ut_init_task(&task);
916 	task.lun = &lun;
917 	task.cdb = cdb;
918 	memset(cdb, 0, sizeof(cdb));
919 	cdb[0] = 0x42; /* UNMAP */
920 	to_be16(&data[7], 2); /* 2 parameters in list */
921 	memset(data, 0, sizeof(data));
922 	to_be16(&data[2], 32); /* 2 descriptors */
923 	to_be64(&data[8], 1); /* LBA 1 */
924 	to_be32(&data[16], 2); /* 2 blocks */
925 	to_be64(&data[24], 10); /* LBA 10 */
926 	to_be32(&data[32], 3); /* 3 blocks */
927 	spdk_scsi_task_set_data(&task, data, sizeof(data));
928 	task.status = SPDK_SCSI_STATUS_GOOD;
929 	g_bdev_io_pool_full = bdev_io_pool_full;
930 	rc = bdev_scsi_execute(&task);
931 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
932 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
933 
934 	ut_bdev_io_flush();
935 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
936 	CU_ASSERT(g_scsi_cb_called == 1);
937 	g_scsi_cb_called = 0;
938 	ut_put_task(&task);
939 
940 	/* Flush 1 block */
941 	ut_init_task(&task);
942 	task.lun = &lun;
943 	task.cdb = cdb;
944 	memset(cdb, 0, sizeof(cdb));
945 	cdb[0] = 0x91; /* SYNCHRONIZE CACHE (16) */
946 	to_be64(&cdb[2], 0); /* LBA */
947 	to_be32(&cdb[10], 1); /* 1 blocks */
948 	g_bdev_io_pool_full = bdev_io_pool_full;
949 	rc = bdev_scsi_execute(&task);
950 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
951 	CU_ASSERT(task.status == 0xFF);
952 
953 	ut_bdev_io_flush();
954 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
955 	CU_ASSERT(g_scsi_cb_called == 1);
956 	g_scsi_cb_called = 0;
957 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
958 
959 	ut_put_task(&task);
960 }
961 
962 static void
963 xfer_test(void)
964 {
965 	_xfer_test(false);
966 	_xfer_test(true);
967 }
968 
969 static void
970 get_dif_ctx_test(void)
971 {
972 	struct spdk_bdev bdev = {};
973 	struct spdk_scsi_task task = {};
974 	struct spdk_dif_ctx dif_ctx = {};
975 	uint8_t cdb[16];
976 	bool ret;
977 
978 	cdb[0] = SPDK_SBC_READ_6;
979 	cdb[1] = 0x12;
980 	cdb[2] = 0x34;
981 	cdb[3] = 0x50;
982 	task.cdb = cdb;
983 	task.offset = 0x6 * 512;
984 
985 	ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx);
986 	CU_ASSERT(ret == true);
987 	CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x123456);
988 
989 	cdb[0] = SPDK_SBC_WRITE_12;
990 	to_be32(&cdb[2], 0x12345670);
991 	task.offset = 0x8 * 512;
992 
993 	ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx);
994 	CU_ASSERT(ret == true);
995 	CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x12345678);
996 
997 	cdb[0] = SPDK_SBC_WRITE_16;
998 	to_be64(&cdb[2], 0x0000000012345670);
999 	task.offset = 0x8 * 512;
1000 
1001 	ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx);
1002 	CU_ASSERT(ret == true);
1003 	CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x12345678);
1004 }
1005 
1006 int
1007 main(int argc, char **argv)
1008 {
1009 	CU_pSuite	suite = NULL;
1010 	unsigned int	num_failures;
1011 
1012 	TAILQ_INIT(&g_bdev_io_queue);
1013 	TAILQ_INIT(&g_io_wait_queue);
1014 
1015 	CU_set_error_action(CUEA_ABORT);
1016 	CU_initialize_registry();
1017 
1018 	suite = CU_add_suite("translation_suite", NULL, NULL);
1019 
1020 	CU_ADD_TEST(suite, mode_select_6_test);
1021 	CU_ADD_TEST(suite, mode_select_6_test2);
1022 	CU_ADD_TEST(suite, mode_sense_6_test);
1023 	CU_ADD_TEST(suite, mode_sense_10_test);
1024 	CU_ADD_TEST(suite, inquiry_evpd_test);
1025 	CU_ADD_TEST(suite, inquiry_standard_test);
1026 	CU_ADD_TEST(suite, inquiry_overflow_test);
1027 	CU_ADD_TEST(suite, task_complete_test);
1028 	CU_ADD_TEST(suite, lba_range_test);
1029 	CU_ADD_TEST(suite, xfer_len_test);
1030 	CU_ADD_TEST(suite, xfer_test);
1031 	CU_ADD_TEST(suite, scsi_name_padding_test);
1032 	CU_ADD_TEST(suite, get_dif_ctx_test);
1033 
1034 	CU_basic_set_mode(CU_BRM_VERBOSE);
1035 	CU_basic_run_tests();
1036 	num_failures = CU_get_number_of_failures();
1037 	CU_cleanup_registry();
1038 	return num_failures;
1039 }
1040