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