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