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