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