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