xref: /spdk/test/unit/lib/scsi/scsi_bdev.c/scsi_bdev_ut.c (revision 4b527a3c150655bbff45ccc340395944d3171d0b)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2016 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/stdinc.h"
7 
8 #include "scsi/task.c"
9 #include "scsi/scsi_bdev.c"
10 #include "common/lib/test_env.c"
11 
12 #include "spdk_internal/cunit.h"
13 
14 #include "spdk_internal/mock.h"
15 #include "spdk/bdev_module.h"
16 
17 SPDK_LOG_REGISTER_COMPONENT(scsi)
18 
19 static uint64_t g_test_bdev_num_blocks;
20 
21 TAILQ_HEAD(, spdk_bdev_io) g_bdev_io_queue;
22 int g_outstanding_bdev_io_count = 0;
23 int g_scsi_cb_called = 0;
24 
25 TAILQ_HEAD(, spdk_bdev_io_wait_entry) g_io_wait_queue;
26 int g_pending_bdev_io_count  = 0;
27 bool g_bdev_io_pool_full = false;
28 int g_bdev_io_pool_count = -1;
29 
30 bool
spdk_bdev_io_type_supported(struct spdk_bdev * bdev,enum spdk_bdev_io_type io_type)31 spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type)
32 {
33 	abort();
34 	return false;
35 }
36 
37 DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io));
38 
39 DEFINE_STUB(spdk_bdev_get_name, const char *,
40 	    (const struct spdk_bdev *bdev), "test");
41 
42 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t,
43 	    (const struct spdk_bdev *bdev), 512);
44 
45 DEFINE_STUB(spdk_bdev_get_acwu, uint16_t,
46 	    (const struct spdk_bdev *bdev), 1);
47 
48 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t,
49 	    (const struct spdk_bdev *bdev), 8);
50 
51 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool,
52 	    (const struct spdk_bdev *bdev), false);
53 
54 DEFINE_STUB(spdk_bdev_get_data_block_size, uint32_t,
55 	    (const struct spdk_bdev *bdev), 512);
56 
57 DEFINE_STUB(spdk_bdev_get_physical_block_size, uint32_t,
58 	    (const struct spdk_bdev *bdev), 4096);
59 
60 uint64_t
spdk_bdev_get_num_blocks(const struct spdk_bdev * bdev)61 spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev)
62 {
63 	return g_test_bdev_num_blocks;
64 }
65 
66 DEFINE_STUB(spdk_bdev_get_product_name, const char *,
67 	    (const struct spdk_bdev *bdev), "test product");
68 
69 DEFINE_STUB(spdk_bdev_has_write_cache, bool,
70 	    (const struct spdk_bdev *bdev), false);
71 
72 DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type,
73 	    (const struct spdk_bdev *bdev), SPDK_DIF_DISABLE);
74 
75 DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool,
76 	    (const struct spdk_bdev *bdev), false);
77 
78 DEFINE_STUB(spdk_bdev_is_dif_check_enabled, bool,
79 	    (const struct spdk_bdev *bdev, enum spdk_dif_check_type check_type), false);
80 
81 DEFINE_STUB(scsi_pr_out, int, (struct spdk_scsi_task *task,
82 			       uint8_t *cdb, uint8_t *data, uint16_t data_len), 0);
83 
84 DEFINE_STUB(scsi_pr_in, int, (struct spdk_scsi_task *task, uint8_t *cdb,
85 			      uint8_t *data, uint16_t data_len), 0);
86 
87 DEFINE_STUB(scsi2_reserve, int, (struct spdk_scsi_task *task, uint8_t *cdb), 0);
88 DEFINE_STUB(scsi2_release, int, (struct spdk_scsi_task *task), 0);
89 
90 void
scsi_lun_complete_task(struct spdk_scsi_lun * lun,struct spdk_scsi_task * task)91 scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)
92 {
93 	g_scsi_cb_called++;
94 }
95 
96 DEFINE_STUB_V(scsi_lun_complete_reset_task,
97 	      (struct spdk_scsi_lun *lun, struct spdk_scsi_task *task));
98 
99 DEFINE_STUB(spdk_scsi_lun_id_int_to_fmt, uint64_t, (int lun_id), 0);
100 
101 DEFINE_STUB(spdk_scsi_dev_get_first_lun, struct spdk_scsi_lun *,
102 	    (struct spdk_scsi_dev *dev), NULL);
103 
104 DEFINE_STUB(spdk_scsi_dev_get_next_lun, struct spdk_scsi_lun *,
105 	    (struct spdk_scsi_lun *prev_lun), NULL);
106 
107 DEFINE_STUB(spdk_scsi_sbc_opcode_string, const char *,
108 	    (uint8_t opcode, uint16_t sa), "UNKNOWN");
109 
110 static void
ut_put_task(struct spdk_scsi_task * task)111 ut_put_task(struct spdk_scsi_task *task)
112 {
113 	if (task->alloc_len) {
114 		free(task->iov.iov_base);
115 	}
116 
117 	task->iov.iov_base = NULL;
118 	task->iov.iov_len = 0;
119 	task->alloc_len = 0;
120 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
121 }
122 
123 static void
ut_init_task(struct spdk_scsi_task * task)124 ut_init_task(struct spdk_scsi_task *task)
125 {
126 	memset(task, 0xFF, sizeof(*task));
127 	task->iov.iov_base = NULL;
128 	task->iovs = &task->iov;
129 	task->iovcnt = 1;
130 	task->alloc_len = 0;
131 	task->dxfer_dir = SPDK_SCSI_DIR_NONE;
132 }
133 
134 void
spdk_bdev_io_get_scsi_status(const struct spdk_bdev_io * bdev_io,int * sc,int * sk,int * asc,int * ascq)135 spdk_bdev_io_get_scsi_status(const struct spdk_bdev_io *bdev_io,
136 			     int *sc, int *sk, int *asc, int *ascq)
137 {
138 	switch (bdev_io->internal.status) {
139 	case SPDK_BDEV_IO_STATUS_SUCCESS:
140 		*sc = SPDK_SCSI_STATUS_GOOD;
141 		*sk = SPDK_SCSI_SENSE_NO_SENSE;
142 		*asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
143 		*ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
144 		break;
145 	case SPDK_BDEV_IO_STATUS_MISCOMPARE:
146 		*sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
147 		*sk = SPDK_SCSI_SENSE_MISCOMPARE;
148 		*asc = SPDK_SCSI_ASC_MISCOMPARE_DURING_VERIFY_OPERATION;
149 		*ascq = bdev_io->internal.error.scsi.ascq;
150 		break;
151 	case SPDK_BDEV_IO_STATUS_SCSI_ERROR:
152 		*sc = bdev_io->internal.error.scsi.sc;
153 		*sk = bdev_io->internal.error.scsi.sk;
154 		*asc = bdev_io->internal.error.scsi.asc;
155 		*ascq = bdev_io->internal.error.scsi.ascq;
156 		break;
157 	default:
158 		*sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
159 		*sk = SPDK_SCSI_SENSE_ABORTED_COMMAND;
160 		*asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
161 		*ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
162 		break;
163 	}
164 }
165 
166 void
spdk_bdev_io_get_iovec(struct spdk_bdev_io * bdev_io,struct iovec ** iovp,int * iovcntp)167 spdk_bdev_io_get_iovec(struct spdk_bdev_io *bdev_io, struct iovec **iovp, int *iovcntp)
168 {
169 	*iovp = NULL;
170 	*iovcntp = 0;
171 }
172 
173 static void
ut_bdev_io_complete(void)174 ut_bdev_io_complete(void)
175 {
176 	struct spdk_bdev_io *bdev_io;
177 
178 	while (!TAILQ_EMPTY(&g_bdev_io_queue)) {
179 		bdev_io = TAILQ_FIRST(&g_bdev_io_queue);
180 		TAILQ_REMOVE(&g_bdev_io_queue, bdev_io, internal.link);
181 		bdev_io->internal.cb(bdev_io, true, bdev_io->internal.caller_ctx);
182 		free(bdev_io);
183 		g_outstanding_bdev_io_count--;
184 		if (g_bdev_io_pool_count != -1) {
185 			g_bdev_io_pool_count++;
186 		}
187 	}
188 }
189 
190 static void
ut_bdev_io_retry(void)191 ut_bdev_io_retry(void)
192 {
193 	struct spdk_bdev_io_wait_entry *entry;
194 
195 	while (!TAILQ_EMPTY(&g_io_wait_queue)) {
196 		entry = TAILQ_FIRST(&g_io_wait_queue);
197 		TAILQ_REMOVE(&g_io_wait_queue, entry, link);
198 		g_pending_bdev_io_count--;
199 		entry->cb_fn(entry->cb_arg);
200 	}
201 }
202 
203 static void
ut_bdev_io_flush(void)204 ut_bdev_io_flush(void)
205 {
206 	while (!TAILQ_EMPTY(&g_bdev_io_queue) || !TAILQ_EMPTY(&g_io_wait_queue)) {
207 		ut_bdev_io_complete();
208 		ut_bdev_io_retry();
209 	}
210 }
211 
212 static int
_spdk_bdev_io_op(spdk_bdev_io_completion_cb cb,void * cb_arg)213 _spdk_bdev_io_op(spdk_bdev_io_completion_cb cb, void *cb_arg)
214 {
215 	struct spdk_bdev_io *bdev_io;
216 
217 	if (g_bdev_io_pool_full) {
218 		g_bdev_io_pool_full = false;
219 		return -ENOMEM;
220 	} else if (g_bdev_io_pool_count == 0) {
221 		return -ENOMEM;
222 	} else if (g_bdev_io_pool_count != -1) {
223 		g_bdev_io_pool_count--;
224 	}
225 
226 	bdev_io = calloc(1, sizeof(*bdev_io));
227 	SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
228 	bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
229 	bdev_io->internal.cb = cb;
230 	bdev_io->internal.caller_ctx = cb_arg;
231 
232 	TAILQ_INSERT_TAIL(&g_bdev_io_queue, bdev_io, internal.link);
233 	g_outstanding_bdev_io_count++;
234 
235 	return 0;
236 }
237 
238 int
spdk_bdev_readv_blocks(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,struct iovec * iov,int iovcnt,uint64_t offset_blocks,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)239 spdk_bdev_readv_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
240 		       struct iovec *iov, int iovcnt,
241 		       uint64_t offset_blocks, uint64_t num_blocks,
242 		       spdk_bdev_io_completion_cb cb, void *cb_arg)
243 {
244 	return _spdk_bdev_io_op(cb, cb_arg);
245 }
246 
247 int
spdk_bdev_writev_blocks(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,struct iovec * iov,int iovcnt,uint64_t offset_blocks,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)248 spdk_bdev_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
249 			struct iovec *iov, int iovcnt,
250 			uint64_t offset_blocks, uint64_t num_blocks,
251 			spdk_bdev_io_completion_cb cb, void *cb_arg)
252 {
253 	return _spdk_bdev_io_op(cb, cb_arg);
254 }
255 
256 int
spdk_bdev_comparev_and_writev_blocks(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,struct iovec * compare_iov,int compare_iovcnt,struct iovec * write_iov,int write_iovcnt,uint64_t offset_blocks,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)257 spdk_bdev_comparev_and_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
258 				     struct iovec *compare_iov, int compare_iovcnt,
259 				     struct iovec *write_iov, int write_iovcnt,
260 				     uint64_t offset_blocks, uint64_t num_blocks,
261 				     spdk_bdev_io_completion_cb cb, void *cb_arg)
262 {
263 	return _spdk_bdev_io_op(cb, cb_arg);
264 }
265 
266 int
spdk_bdev_unmap_blocks(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,uint64_t offset_blocks,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)267 spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
268 		       uint64_t offset_blocks, uint64_t num_blocks,
269 		       spdk_bdev_io_completion_cb cb, void *cb_arg)
270 {
271 	return _spdk_bdev_io_op(cb, cb_arg);
272 }
273 
274 int
spdk_bdev_reset(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,spdk_bdev_io_completion_cb cb,void * cb_arg)275 spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
276 		spdk_bdev_io_completion_cb cb, void *cb_arg)
277 {
278 	return _spdk_bdev_io_op(cb, cb_arg);
279 }
280 
281 int
spdk_bdev_flush_blocks(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,uint64_t offset_blocks,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)282 spdk_bdev_flush_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
283 		       uint64_t offset_blocks, uint64_t num_blocks,
284 		       spdk_bdev_io_completion_cb cb, void *cb_arg)
285 {
286 	return _spdk_bdev_io_op(cb, cb_arg);
287 }
288 
289 int
spdk_bdev_queue_io_wait(struct spdk_bdev * bdev,struct spdk_io_channel * ch,struct spdk_bdev_io_wait_entry * entry)290 spdk_bdev_queue_io_wait(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
291 			struct spdk_bdev_io_wait_entry *entry)
292 {
293 	TAILQ_INSERT_TAIL(&g_io_wait_queue, entry, link);
294 	g_pending_bdev_io_count++;
295 	return 0;
296 }
297 
298 int
spdk_dif_ctx_init(struct spdk_dif_ctx * ctx,uint32_t block_size,uint32_t md_size,bool md_interleave,bool dif_loc,enum spdk_dif_type dif_type,uint32_t dif_flags,uint32_t init_ref_tag,uint16_t apptag_mask,uint16_t app_tag,uint32_t data_offset,uint64_t guard_seed,struct spdk_dif_ctx_init_ext_opts * opts)299 spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size,
300 		  bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
301 		  uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag,
302 		  uint32_t data_offset, uint64_t guard_seed, struct spdk_dif_ctx_init_ext_opts *opts)
303 {
304 	ctx->dif_pi_format = opts->dif_pi_format;
305 	ctx->init_ref_tag = init_ref_tag;
306 	ctx->ref_tag_offset = data_offset / 512;
307 	return 0;
308 }
309 
310 /*
311  * This test specifically tests a mode select 6 command from the
312  *  Windows SCSI compliance test that caused SPDK to crash.
313  */
314 static void
mode_select_6_test(void)315 mode_select_6_test(void)
316 {
317 	struct spdk_bdev bdev;
318 	struct spdk_scsi_task task;
319 	struct spdk_scsi_lun lun;
320 	struct spdk_scsi_dev dev;
321 	char cdb[16];
322 	char data[24];
323 	int rc;
324 
325 	ut_init_task(&task);
326 
327 	cdb[0] = 0x15;
328 	cdb[1] = 0x11;
329 	cdb[2] = 0x00;
330 	cdb[3] = 0x00;
331 	cdb[4] = 0x18;
332 	cdb[5] = 0x00;
333 	task.cdb = cdb;
334 
335 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
336 	lun.bdev = &bdev;
337 	lun.dev = &dev;
338 	task.lun = &lun;
339 
340 	memset(data, 0, sizeof(data));
341 	data[4] = 0x08;
342 	data[5] = 0x02;
343 	spdk_scsi_task_set_data(&task, data, sizeof(data));
344 
345 	rc = bdev_scsi_execute(&task);
346 
347 	CU_ASSERT_EQUAL(rc, 0);
348 
349 	ut_put_task(&task);
350 }
351 
352 /*
353  * This test specifically tests a mode select 6 command which
354  *  contains no mode pages.
355  */
356 static void
mode_select_6_test2(void)357 mode_select_6_test2(void)
358 {
359 	struct spdk_bdev bdev;
360 	struct spdk_scsi_task task;
361 	struct spdk_scsi_lun lun;
362 	struct spdk_scsi_dev dev;
363 	char cdb[16];
364 	int rc;
365 
366 	ut_init_task(&task);
367 
368 	cdb[0] = 0x15;
369 	cdb[1] = 0x00;
370 	cdb[2] = 0x00;
371 	cdb[3] = 0x00;
372 	cdb[4] = 0x00;
373 	cdb[5] = 0x00;
374 	task.cdb = cdb;
375 
376 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
377 	lun.bdev = &bdev;
378 	lun.dev = &dev;
379 	task.lun = &lun;
380 
381 	rc = bdev_scsi_execute(&task);
382 
383 	CU_ASSERT_EQUAL(rc, 0);
384 
385 	ut_put_task(&task);
386 }
387 
388 /*
389  * This test specifically tests a mode sense 6 command which
390  *  return all subpage 00h mode pages.
391  */
392 static void
mode_sense_6_test(void)393 mode_sense_6_test(void)
394 {
395 	struct spdk_bdev bdev;
396 	struct spdk_scsi_task task;
397 	struct spdk_scsi_lun lun;
398 	struct spdk_scsi_dev dev;
399 	char cdb[12];
400 	unsigned char *data;
401 	int rc;
402 	unsigned char mode_data_len = 0;
403 	unsigned char medium_type = 0;
404 	unsigned char dev_specific_param = 0;
405 	unsigned char blk_descriptor_len = 0;
406 
407 	memset(&bdev, 0, sizeof(struct spdk_bdev));
408 	ut_init_task(&task);
409 	memset(cdb, 0, sizeof(cdb));
410 
411 	cdb[0] = 0x1A;
412 	cdb[2] = 0x3F;
413 	cdb[4] = 0xFF;
414 	task.cdb = cdb;
415 
416 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
417 	lun.bdev = &bdev;
418 	lun.dev = &dev;
419 	task.lun = &lun;
420 
421 	rc = bdev_scsi_execute(&task);
422 	SPDK_CU_ASSERT_FATAL(rc == 0);
423 
424 	data = task.iovs[0].iov_base;
425 	mode_data_len = data[0];
426 	medium_type = data[1];
427 	dev_specific_param = data[2];
428 	blk_descriptor_len = data[3];
429 
430 	CU_ASSERT(mode_data_len >= 11);
431 	CU_ASSERT_EQUAL(medium_type, 0);
432 	CU_ASSERT_EQUAL(dev_specific_param, 0);
433 	CU_ASSERT_EQUAL(blk_descriptor_len, 8);
434 
435 	ut_put_task(&task);
436 }
437 
438 /*
439  * This test specifically tests a mode sense 10 command which
440  *  return all subpage 00h mode pages.
441  */
442 static void
mode_sense_10_test(void)443 mode_sense_10_test(void)
444 {
445 	struct spdk_bdev bdev;
446 	struct spdk_scsi_task task;
447 	struct spdk_scsi_lun lun;
448 	struct spdk_scsi_dev dev;
449 	char cdb[12];
450 	unsigned char *data;
451 	int rc;
452 	unsigned short mode_data_len = 0;
453 	unsigned char medium_type = 0;
454 	unsigned char dev_specific_param = 0;
455 	unsigned short blk_descriptor_len = 0;
456 
457 	memset(&bdev, 0, sizeof(struct spdk_bdev));
458 	ut_init_task(&task);
459 	memset(cdb, 0, sizeof(cdb));
460 	cdb[0] = 0x5A;
461 	cdb[2] = 0x3F;
462 	cdb[8] = 0xFF;
463 	task.cdb = cdb;
464 
465 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
466 	lun.bdev = &bdev;
467 	lun.dev = &dev;
468 	task.lun = &lun;
469 
470 	rc = bdev_scsi_execute(&task);
471 	SPDK_CU_ASSERT_FATAL(rc == 0);
472 
473 	data = task.iovs[0].iov_base;
474 	mode_data_len = ((data[0] << 8) + data[1]);
475 	medium_type = data[2];
476 	dev_specific_param = data[3];
477 	blk_descriptor_len = ((data[6] << 8) + data[7]);
478 
479 	CU_ASSERT(mode_data_len >= 14);
480 	CU_ASSERT_EQUAL(medium_type, 0);
481 	CU_ASSERT_EQUAL(dev_specific_param, 0);
482 	CU_ASSERT_EQUAL(blk_descriptor_len, 8);
483 
484 	ut_put_task(&task);
485 }
486 
487 /*
488  * This test specifically tests a scsi inquiry command from the
489  *  Windows SCSI compliance test that failed to return the
490  *  expected SCSI error sense code.
491  */
492 static void
inquiry_evpd_test(void)493 inquiry_evpd_test(void)
494 {
495 	struct spdk_bdev bdev;
496 	struct spdk_scsi_task task;
497 	struct spdk_scsi_lun lun;
498 	struct spdk_scsi_dev dev;
499 	char cdb[6];
500 	int rc;
501 
502 	ut_init_task(&task);
503 
504 	cdb[0] = 0x12;
505 	cdb[1] = 0x00;	/* EVPD = 0 */
506 	cdb[2] = 0xff;	/* PageCode non-zero */
507 	cdb[3] = 0x00;
508 	cdb[4] = 0xff;
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 	rc = bdev_scsi_execute(&task);
518 	SPDK_CU_ASSERT_FATAL(rc == 0);
519 
520 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
521 	CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ILLEGAL_REQUEST);
522 	CU_ASSERT_EQUAL(task.sense_data[12], 0x24);
523 	CU_ASSERT_EQUAL(task.sense_data[13], 0x0);
524 
525 	ut_put_task(&task);
526 }
527 
528 /*
529  * This test is to verify specific return data for a standard scsi inquiry
530  *  command: Version
531  */
532 static void
inquiry_standard_test(void)533 inquiry_standard_test(void)
534 {
535 	struct spdk_bdev bdev = { .blocklen = 512 };
536 	struct spdk_scsi_task task;
537 	struct spdk_scsi_lun lun;
538 	struct spdk_scsi_dev dev;
539 	char cdb[6];
540 	char *data;
541 	struct spdk_scsi_cdb_inquiry_data *inq_data;
542 	int rc;
543 
544 	ut_init_task(&task);
545 
546 	cdb[0] = 0x12;
547 	cdb[1] = 0x00;	/* EVPD = 0 */
548 	cdb[2] = 0x00;	/* PageCode zero - requesting standard inquiry */
549 	cdb[3] = 0x00;
550 	cdb[4] = 0xff;	/* Indicate data size used by conformance test */
551 	cdb[5] = 0x00;
552 	task.cdb = cdb;
553 
554 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
555 	lun.bdev = &bdev;
556 	lun.dev = &dev;
557 	task.lun = &lun;
558 
559 	rc = bdev_scsi_execute(&task);
560 
561 	data = task.iovs[0].iov_base;
562 	inq_data = (struct spdk_scsi_cdb_inquiry_data *)&data[0];
563 
564 	CU_ASSERT_EQUAL(inq_data->version, SPDK_SPC_VERSION_SPC3);
565 	CU_ASSERT_EQUAL(rc, 0);
566 
567 	ut_put_task(&task);
568 }
569 
570 static void
_inquiry_overflow_test(uint8_t alloc_len)571 _inquiry_overflow_test(uint8_t alloc_len)
572 {
573 	struct spdk_bdev bdev = { .blocklen = 512 };
574 	struct spdk_scsi_task task;
575 	struct spdk_scsi_lun lun;
576 	struct spdk_scsi_dev dev;
577 	uint8_t cdb[6];
578 	int rc;
579 	/* expects a 4K internal data buffer */
580 	char data[4096], data_compare[4096];
581 
582 	ut_init_task(&task);
583 
584 	cdb[0] = 0x12;
585 	cdb[1] = 0x00;		/* EVPD = 0 */
586 	cdb[2] = 0x00;		/* PageCode zero - requesting standard inquiry */
587 	cdb[3] = 0x00;
588 	cdb[4] = alloc_len;	/* Indicate data size used by conformance test */
589 	cdb[5] = 0x00;
590 	task.cdb = cdb;
591 
592 	snprintf(&dev.name[0], sizeof(dev.name), "spdk_iscsi_translation_test");
593 	lun.bdev = &bdev;
594 	lun.dev = &dev;
595 	task.lun = &lun;
596 
597 	memset(data, 0, sizeof(data));
598 	memset(data_compare, 0, sizeof(data_compare));
599 
600 	spdk_scsi_task_set_data(&task, data, sizeof(data));
601 
602 	rc = bdev_scsi_execute(&task);
603 	SPDK_CU_ASSERT_FATAL(rc == 0);
604 
605 	CU_ASSERT_EQUAL(memcmp(data + alloc_len, data_compare + alloc_len, sizeof(data) - alloc_len), 0);
606 	CU_ASSERT(task.data_transferred <= alloc_len);
607 
608 	ut_put_task(&task);
609 }
610 
611 static void
inquiry_overflow_test(void)612 inquiry_overflow_test(void)
613 {
614 	int i;
615 
616 	for (i = 0; i < 256; i++) {
617 		_inquiry_overflow_test(i);
618 	}
619 }
620 
621 static void
scsi_name_padding_test(void)622 scsi_name_padding_test(void)
623 {
624 	char name[SPDK_SCSI_DEV_MAX_NAME + 1];
625 	char buf[SPDK_SCSI_DEV_MAX_NAME + 1];
626 	int written, i;
627 
628 	/* case 1 */
629 	memset(name, '\0', sizeof(name));
630 	memset(name, 'x', 251);
631 	written = bdev_scsi_pad_scsi_name(buf, name);
632 
633 	CU_ASSERT(written == 252);
634 	CU_ASSERT(buf[250] == 'x');
635 	CU_ASSERT(buf[251] == '\0');
636 
637 	/* case 2:  */
638 	memset(name, '\0', sizeof(name));
639 	memset(name, 'x', 252);
640 	written = bdev_scsi_pad_scsi_name(buf, name);
641 
642 	CU_ASSERT(written == 256);
643 	CU_ASSERT(buf[251] == 'x');
644 	for (i = 252; i < 256; i++) {
645 		CU_ASSERT(buf[i] == '\0');
646 	}
647 
648 	/* case 3 */
649 	memset(name, '\0', sizeof(name));
650 	memset(name, 'x', 255);
651 	written = bdev_scsi_pad_scsi_name(buf, name);
652 
653 	CU_ASSERT(written == 256);
654 	CU_ASSERT(buf[254] == 'x');
655 	CU_ASSERT(buf[255] == '\0');
656 }
657 
658 /*
659  * This test is to verify specific error translation from bdev to scsi.
660  */
661 static void
task_complete_test(void)662 task_complete_test(void)
663 {
664 	struct spdk_scsi_task task;
665 	struct spdk_bdev_io bdev_io = {};
666 	struct spdk_scsi_lun lun;
667 
668 	ut_init_task(&task);
669 
670 	TAILQ_INIT(&lun.tasks);
671 	TAILQ_INSERT_TAIL(&lun.tasks, &task, scsi_link);
672 	task.lun = &lun;
673 
674 	bdev_io.internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
675 	bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task);
676 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD);
677 	CU_ASSERT(g_scsi_cb_called == 1);
678 	g_scsi_cb_called = 0;
679 
680 	bdev_io.internal.status = SPDK_BDEV_IO_STATUS_SCSI_ERROR;
681 	bdev_io.internal.error.scsi.sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
682 	bdev_io.internal.error.scsi.sk = SPDK_SCSI_SENSE_HARDWARE_ERROR;
683 	bdev_io.internal.error.scsi.asc = SPDK_SCSI_ASC_WARNING;
684 	bdev_io.internal.error.scsi.ascq = SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED;
685 	bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task);
686 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
687 	CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_HARDWARE_ERROR);
688 	CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_WARNING);
689 	CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED);
690 	CU_ASSERT(g_scsi_cb_called == 1);
691 	g_scsi_cb_called = 0;
692 
693 	bdev_io.internal.status = SPDK_BDEV_IO_STATUS_FAILED;
694 	bdev_scsi_task_complete_cmd(&bdev_io, bdev_io.internal.status, &task);
695 	CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
696 	CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ABORTED_COMMAND);
697 	CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE);
698 	CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
699 	CU_ASSERT(g_scsi_cb_called == 1);
700 	g_scsi_cb_called = 0;
701 
702 	ut_put_task(&task);
703 }
704 
705 static void
lba_range_test(void)706 lba_range_test(void)
707 {
708 	struct spdk_bdev bdev = { .blocklen = 512 };
709 	struct spdk_scsi_lun lun;
710 	struct spdk_scsi_task task;
711 	uint8_t cdb[16];
712 	int rc;
713 
714 	lun.bdev = &bdev;
715 
716 	ut_init_task(&task);
717 	task.lun = &lun;
718 	task.lun->bdev_desc = NULL;
719 	task.lun->io_channel = NULL;
720 	task.cdb = cdb;
721 
722 	memset(cdb, 0, sizeof(cdb));
723 	cdb[0] = 0x88; /* READ (16) */
724 
725 	/* Test block device size of 4 blocks */
726 	g_test_bdev_num_blocks = 4;
727 
728 	/* LBA = 0, length = 1 (in range) */
729 	to_be64(&cdb[2], 0); /* LBA */
730 	to_be32(&cdb[10], 1); /* transfer length */
731 	task.transfer_len = 1 * 512;
732 	task.offset = 0;
733 	task.length = 1 * 512;
734 	rc = bdev_scsi_execute(&task);
735 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
736 	CU_ASSERT(task.status == 0xFF);
737 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
738 	ut_bdev_io_flush();
739 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
740 	CU_ASSERT(g_scsi_cb_called == 1);
741 	g_scsi_cb_called = 0;
742 
743 	/* LBA = 4, length = 1 (LBA out of range) */
744 	to_be64(&cdb[2], 4); /* LBA */
745 	to_be32(&cdb[10], 1); /* transfer length */
746 	task.transfer_len = 1 * 512;
747 	task.offset = 0;
748 	task.length = 1 * 512;
749 	rc = bdev_scsi_execute(&task);
750 	CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
751 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
752 	CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
753 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
754 
755 	/* LBA = 0, length = 4 (in range, max valid size) */
756 	to_be64(&cdb[2], 0); /* LBA */
757 	to_be32(&cdb[10], 4); /* transfer length */
758 	task.transfer_len = 4 * 512;
759 	task.status = 0xFF;
760 	task.offset = 0;
761 	task.length = 1 * 512;
762 	rc = bdev_scsi_execute(&task);
763 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
764 	CU_ASSERT(task.status == 0xFF);
765 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
766 	ut_bdev_io_flush();
767 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
768 	CU_ASSERT(g_scsi_cb_called == 1);
769 	g_scsi_cb_called = 0;
770 
771 	/* LBA = 0, length = 5 (LBA in range, length beyond end of bdev) */
772 	to_be64(&cdb[2], 0); /* LBA */
773 	to_be32(&cdb[10], 5); /* transfer length */
774 	task.transfer_len = 5 * 512;
775 	task.offset = 0;
776 	task.length = 1 * 512;
777 	rc = 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[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
781 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
782 
783 	ut_put_task(&task);
784 }
785 
786 static void
xfer_len_test(void)787 xfer_len_test(void)
788 {
789 	struct spdk_bdev bdev = { .blocklen = 512 };
790 	struct spdk_scsi_lun lun;
791 	struct spdk_scsi_task task;
792 	uint8_t cdb[16];
793 	int rc;
794 
795 	lun.bdev = &bdev;
796 
797 	ut_init_task(&task);
798 	task.lun = &lun;
799 	task.lun->bdev_desc = NULL;
800 	task.lun->io_channel = NULL;
801 	task.cdb = cdb;
802 
803 	memset(cdb, 0, sizeof(cdb));
804 	cdb[0] = 0x88; /* READ (16) */
805 
806 	/* Test block device size of 512 MiB */
807 	g_test_bdev_num_blocks = 512 * 1024 * 1024;
808 
809 	/* 1 block */
810 	to_be64(&cdb[2], 0); /* LBA */
811 	to_be32(&cdb[10], 1); /* transfer length */
812 	task.transfer_len = 1 * 512;
813 	task.offset = 0;
814 	task.length = 1 * 512;
815 	rc = bdev_scsi_execute(&task);
816 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
817 	CU_ASSERT(task.status == 0xFF);
818 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
819 	ut_bdev_io_flush();
820 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
821 	CU_ASSERT(g_scsi_cb_called == 1);
822 	g_scsi_cb_called = 0;
823 
824 	/* max transfer length (as reported in block limits VPD page) */
825 	to_be64(&cdb[2], 0); /* LBA */
826 	to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512); /* transfer length */
827 	task.transfer_len = SPDK_WORK_BLOCK_SIZE;
828 	task.status = 0xFF;
829 	task.offset = 0;
830 	task.length = 1 * 512;
831 	rc = bdev_scsi_execute(&task);
832 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
833 	CU_ASSERT(task.status == 0xFF);
834 	SPDK_CU_ASSERT_FATAL(!TAILQ_EMPTY(&g_bdev_io_queue));
835 	ut_bdev_io_flush();
836 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
837 	CU_ASSERT(g_scsi_cb_called == 1);
838 	g_scsi_cb_called = 0;
839 
840 	/* max transfer length plus one block (invalid) */
841 	to_be64(&cdb[2], 0); /* LBA */
842 	to_be32(&cdb[10], SPDK_WORK_BLOCK_SIZE / 512 + 1); /* transfer length */
843 	task.transfer_len = SPDK_WORK_BLOCK_SIZE + 512;
844 	task.offset = 0;
845 	task.length = 1 * 512;
846 	rc = bdev_scsi_execute(&task);
847 	CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
848 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
849 	CU_ASSERT((task.sense_data[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST);
850 	CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB);
851 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
852 
853 	/* zero transfer length (valid) */
854 	to_be64(&cdb[2], 0); /* LBA */
855 	to_be32(&cdb[10], 0); /* transfer length */
856 	task.transfer_len = 0;
857 	task.offset = 0;
858 	task.length = 0;
859 	rc = bdev_scsi_execute(&task);
860 	CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
861 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
862 	CU_ASSERT(task.data_transferred == 0);
863 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
864 
865 	/* zero transfer length past end of disk (invalid) */
866 	to_be64(&cdb[2], g_test_bdev_num_blocks); /* LBA */
867 	to_be32(&cdb[10], 0); /* transfer length */
868 	task.transfer_len = 0;
869 	task.offset = 0;
870 	task.length = 0;
871 	rc = bdev_scsi_execute(&task);
872 	CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
873 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
874 	CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
875 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
876 
877 	ut_put_task(&task);
878 }
879 
880 static void
_xfer_test(bool bdev_io_pool_full)881 _xfer_test(bool bdev_io_pool_full)
882 {
883 	struct spdk_bdev bdev = { .blocklen = 512 };
884 	struct spdk_scsi_lun lun;
885 	struct spdk_scsi_task task;
886 	uint8_t cdb[16];
887 	char data[4096];
888 	int rc;
889 
890 	lun.bdev = &bdev;
891 
892 	/* Test block device size of 512 MiB */
893 	g_test_bdev_num_blocks = 512 * 1024 * 1024;
894 
895 	/* Read 1 block */
896 	ut_init_task(&task);
897 	task.lun = &lun;
898 	task.lun->bdev_desc = NULL;
899 	task.lun->io_channel = NULL;
900 	task.cdb = cdb;
901 	memset(cdb, 0, sizeof(cdb));
902 	cdb[0] = 0x88; /* READ (16) */
903 	to_be64(&cdb[2], 0); /* LBA */
904 	to_be32(&cdb[10], 1); /* transfer length */
905 	task.transfer_len = 1 * 512;
906 	task.offset = 0;
907 	task.length = 1 * 512;
908 	g_bdev_io_pool_full = bdev_io_pool_full;
909 	rc = bdev_scsi_execute(&task);
910 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
911 	CU_ASSERT(task.status == 0xFF);
912 
913 	ut_bdev_io_flush();
914 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
915 	CU_ASSERT(g_scsi_cb_called == 1);
916 	g_scsi_cb_called = 0;
917 	ut_put_task(&task);
918 
919 	/* Write 1 block */
920 	ut_init_task(&task);
921 	task.lun = &lun;
922 	task.cdb = cdb;
923 	memset(cdb, 0, sizeof(cdb));
924 	cdb[0] = 0x8a; /* WRITE (16) */
925 	to_be64(&cdb[2], 0); /* LBA */
926 	to_be32(&cdb[10], 1); /* transfer length */
927 	task.transfer_len = 1 * 512;
928 	task.offset = 0;
929 	task.length = 1 * 512;
930 	g_bdev_io_pool_full = bdev_io_pool_full;
931 	rc = bdev_scsi_execute(&task);
932 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
933 	CU_ASSERT(task.status == 0xFF);
934 
935 	ut_bdev_io_flush();
936 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
937 	CU_ASSERT(g_scsi_cb_called == 1);
938 	g_scsi_cb_called = 0;
939 	ut_put_task(&task);
940 
941 	/* Unmap 5 blocks using 2 descriptors */
942 	ut_init_task(&task);
943 	task.lun = &lun;
944 	task.cdb = cdb;
945 	memset(cdb, 0, sizeof(cdb));
946 	cdb[0] = 0x42; /* UNMAP */
947 	to_be16(&data[7], 2); /* 2 parameters in list */
948 	memset(data, 0, sizeof(data));
949 	to_be16(&data[2], 32); /* 2 descriptors */
950 	to_be64(&data[8], 1); /* LBA 1 */
951 	to_be32(&data[16], 2); /* 2 blocks */
952 	to_be64(&data[24], 10); /* LBA 10 */
953 	to_be32(&data[32], 3); /* 3 blocks */
954 	spdk_scsi_task_set_data(&task, data, sizeof(data));
955 	task.status = SPDK_SCSI_STATUS_GOOD;
956 	g_bdev_io_pool_full = bdev_io_pool_full;
957 	rc = bdev_scsi_execute(&task);
958 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
959 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
960 
961 	ut_bdev_io_flush();
962 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
963 	CU_ASSERT(g_scsi_cb_called == 1);
964 	g_scsi_cb_called = 0;
965 	ut_put_task(&task);
966 
967 	/* Flush 1 block */
968 	ut_init_task(&task);
969 	task.lun = &lun;
970 	task.cdb = cdb;
971 	memset(cdb, 0, sizeof(cdb));
972 	cdb[0] = 0x91; /* SYNCHRONIZE CACHE (16) */
973 	to_be64(&cdb[2], 0); /* LBA */
974 	to_be32(&cdb[10], 1); /* 1 blocks */
975 	g_bdev_io_pool_full = bdev_io_pool_full;
976 	rc = bdev_scsi_execute(&task);
977 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
978 	CU_ASSERT(task.status == 0xFF);
979 
980 	ut_bdev_io_flush();
981 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
982 	CU_ASSERT(g_scsi_cb_called == 1);
983 	g_scsi_cb_called = 0;
984 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
985 
986 	ut_put_task(&task);
987 }
988 
989 static void
xfer_test(void)990 xfer_test(void)
991 {
992 	_xfer_test(false);
993 	_xfer_test(true);
994 }
995 
996 static void
get_dif_ctx_test(void)997 get_dif_ctx_test(void)
998 {
999 	struct spdk_bdev bdev = {};
1000 	struct spdk_scsi_task task = {};
1001 	struct spdk_dif_ctx dif_ctx = {};
1002 	uint8_t cdb[16];
1003 	bool ret;
1004 
1005 	cdb[0] = SPDK_SBC_READ_6;
1006 	cdb[1] = 0x12;
1007 	cdb[2] = 0x34;
1008 	cdb[3] = 0x50;
1009 	task.cdb = cdb;
1010 	task.offset = 0x6 * 512;
1011 
1012 	ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx);
1013 	CU_ASSERT(ret == true);
1014 	CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x123456);
1015 
1016 	cdb[0] = SPDK_SBC_WRITE_12;
1017 	to_be32(&cdb[2], 0x12345670);
1018 	task.offset = 0x8 * 512;
1019 
1020 	ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx);
1021 	CU_ASSERT(ret == true);
1022 	CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x12345678);
1023 
1024 	cdb[0] = SPDK_SBC_WRITE_16;
1025 	to_be64(&cdb[2], 0x0000000012345670);
1026 	task.offset = 0x8 * 512;
1027 
1028 	ret = bdev_scsi_get_dif_ctx(&bdev, &task, &dif_ctx);
1029 	CU_ASSERT(ret == true);
1030 	CU_ASSERT(dif_ctx.init_ref_tag + dif_ctx.ref_tag_offset == 0x12345678);
1031 }
1032 
1033 static void
unmap_split_test(void)1034 unmap_split_test(void)
1035 {
1036 	struct spdk_bdev bdev = { .blocklen = 512 };
1037 	struct spdk_scsi_lun lun;
1038 	struct spdk_scsi_task task;
1039 	uint8_t cdb[16];
1040 	char data[4096];
1041 	int rc;
1042 
1043 	lun.bdev = &bdev;
1044 
1045 	/* Test block device size of 512 MiB */
1046 	g_test_bdev_num_blocks = 512 * 1024 * 1024;
1047 
1048 	/* Unmap 5 blocks using 6 descriptors(descriptor 2 has 0 blocks). bdev_io pool size is 2.
1049 	 * Hence, unmap should be done by 3 iterations.
1050 	 * 1st - 2 unmaps(0, 1), 2nd - 3 unmaps(2, 3, 4), and 3rd - 1 unmap(5).
1051 	 */
1052 	ut_init_task(&task);
1053 	task.lun = &lun;
1054 	task.cdb = cdb;
1055 	memset(cdb, 0, sizeof(cdb));
1056 	cdb[0] = 0x42; /* UNMAP */
1057 	to_be16(&data[7], 6); /* 6 parameters in list */
1058 	memset(data, 0, sizeof(data));
1059 	to_be16(&data[2], 16 * 6); /* 6 descriptors */
1060 	to_be64(&data[8], 1); /* LBA 1 */
1061 	to_be32(&data[16], 2); /* 2 blocks */
1062 	to_be64(&data[24], 5); /* LBA 5 */
1063 	to_be32(&data[32], 3); /* 3 blocks */
1064 	to_be64(&data[40], 10); /* LBA 10 */
1065 	to_be32(&data[48], 0); /* 0 block */
1066 	to_be64(&data[56], 15); /* LBA 15 */
1067 	to_be32(&data[64], 4); /* 4 blocks */
1068 	to_be64(&data[72], 30); /* LBA 30 */
1069 	to_be32(&data[80], 1); /* 1 block */
1070 	to_be64(&data[88], 40); /* LBA 40 */
1071 	to_be32(&data[96], 1); /* 1 block */
1072 	spdk_scsi_task_set_data(&task, data, sizeof(data));
1073 	task.status = SPDK_SCSI_STATUS_GOOD;
1074 
1075 	g_bdev_io_pool_full = true;
1076 
1077 	rc = bdev_scsi_execute(&task);
1078 	CU_ASSERT(rc == SPDK_SCSI_TASK_PENDING);
1079 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
1080 	CU_ASSERT(g_scsi_cb_called == 0);
1081 	CU_ASSERT(g_outstanding_bdev_io_count == 0);
1082 	CU_ASSERT(g_pending_bdev_io_count == 1);
1083 
1084 	g_bdev_io_pool_count = 2;
1085 	ut_bdev_io_retry();
1086 
1087 	/* descriptor 0 and 1 */
1088 	CU_ASSERT(g_outstanding_bdev_io_count == 2);
1089 	CU_ASSERT(g_pending_bdev_io_count == 0);
1090 
1091 	g_bdev_io_pool_full = true;
1092 	ut_bdev_io_complete();
1093 
1094 	CU_ASSERT(g_outstanding_bdev_io_count == 0);
1095 	CU_ASSERT(g_pending_bdev_io_count == 1);
1096 
1097 	ut_bdev_io_retry();
1098 
1099 	/* descriptor 2 and 3 (descriptor 2 is valid even though it is 0 blocks) */
1100 	CU_ASSERT(g_outstanding_bdev_io_count == 2);
1101 	CU_ASSERT(g_pending_bdev_io_count == 0);
1102 
1103 	g_bdev_io_pool_full = true;
1104 	ut_bdev_io_complete();
1105 
1106 	CU_ASSERT(g_outstanding_bdev_io_count == 0);
1107 	CU_ASSERT(g_pending_bdev_io_count == 1);
1108 
1109 	ut_bdev_io_retry();
1110 
1111 	/* descriptor 4 and 5 */
1112 	CU_ASSERT(g_outstanding_bdev_io_count == 2);
1113 	CU_ASSERT(g_pending_bdev_io_count == 0);
1114 
1115 	ut_bdev_io_complete();
1116 
1117 	CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
1118 	CU_ASSERT(g_scsi_cb_called == 1);
1119 
1120 	g_scsi_cb_called = 0;
1121 	g_bdev_io_pool_count = -1;
1122 
1123 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_bdev_io_queue));
1124 	SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&g_io_wait_queue));
1125 
1126 	ut_put_task(&task);
1127 }
1128 
1129 int
main(int argc,char ** argv)1130 main(int argc, char **argv)
1131 {
1132 	CU_pSuite	suite = NULL;
1133 	unsigned int	num_failures;
1134 
1135 	TAILQ_INIT(&g_bdev_io_queue);
1136 	TAILQ_INIT(&g_io_wait_queue);
1137 
1138 	CU_initialize_registry();
1139 
1140 	suite = CU_add_suite("translation_suite", NULL, NULL);
1141 
1142 	CU_ADD_TEST(suite, mode_select_6_test);
1143 	CU_ADD_TEST(suite, mode_select_6_test2);
1144 	CU_ADD_TEST(suite, mode_sense_6_test);
1145 	CU_ADD_TEST(suite, mode_sense_10_test);
1146 	CU_ADD_TEST(suite, inquiry_evpd_test);
1147 	CU_ADD_TEST(suite, inquiry_standard_test);
1148 	CU_ADD_TEST(suite, inquiry_overflow_test);
1149 	CU_ADD_TEST(suite, task_complete_test);
1150 	CU_ADD_TEST(suite, lba_range_test);
1151 	CU_ADD_TEST(suite, xfer_len_test);
1152 	CU_ADD_TEST(suite, xfer_test);
1153 	CU_ADD_TEST(suite, scsi_name_padding_test);
1154 	CU_ADD_TEST(suite, get_dif_ctx_test);
1155 	CU_ADD_TEST(suite, unmap_split_test);
1156 
1157 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
1158 	CU_cleanup_registry();
1159 	return num_failures;
1160 }
1161