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