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