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