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