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