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