From d33a0438a4f7082ae51f173070666cf80511ce4f Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Mon, 22 Dec 2014 07:52:51 -0800 Subject: [PATCH] TESTS: replace read* flags tests with dedicated dpo/fua tests Remove the flags tests for READ* and replace them with a test for the DPO and FUA bits. IF the device claims DPOFUA support in modesense then the READ* CDBs MUST allow these two flags. IF the device does NOT claim DPOFUA then any READ* CDB with these flags must fail with invalod field in cdb. Signed-off-by: Ronnie Sahlberg --- test-tool/Makefile.am | 21 ++-- test-tool/iscsi-test-cu.c | 21 ++-- test-tool/iscsi-test-cu.h | 21 ++-- test-tool/test_compareandwrite_dpofua.c | 127 ++++++++++++++++++++++ test-tool/test_orwrite_dpofua.c | 137 +++++++++++++++++++++++ test-tool/test_orwrite_flags.c | 78 -------------- test-tool/test_read10_dpofua.c | 126 ++++++++++++++++++++++ test-tool/test_read10_flags.c | 71 ------------ test-tool/test_read12_dpofua.c | 125 +++++++++++++++++++++ test-tool/test_read12_flags.c | 76 ------------- test-tool/test_read16_dpofua.c | 126 ++++++++++++++++++++++ test-tool/test_read16_flags.c | 76 ------------- test-tool/test_verify10_dpo.c | 115 ++++++++++++++++++++ test-tool/test_verify10_flags.c | 11 +- test-tool/test_verify12_dpo.c | 115 ++++++++++++++++++++ test-tool/test_verify12_flags.c | 11 +- test-tool/test_verify16_dpo.c | 115 ++++++++++++++++++++ test-tool/test_verify16_flags.c | 12 +-- test-tool/test_write10_dpofua.c | 128 ++++++++++++++++++++++ test-tool/test_write12_dpofua.c | 138 ++++++++++++++++++++++++ test-tool/test_write16_dpofua.c | 138 ++++++++++++++++++++++++ test-tool/test_writeverify10_dpo.c | 115 ++++++++++++++++++++ test-tool/test_writeverify10_flags.c | 11 +- test-tool/test_writeverify12_dpo.c | 115 ++++++++++++++++++++ test-tool/test_writeverify12_flags.c | 11 +- test-tool/test_writeverify16_dpo.c | 116 ++++++++++++++++++++ test-tool/test_writeverify16_flags.c | 11 +- 27 files changed, 1794 insertions(+), 373 deletions(-) create mode 100644 test-tool/test_compareandwrite_dpofua.c create mode 100644 test-tool/test_orwrite_dpofua.c delete mode 100644 test-tool/test_orwrite_flags.c create mode 100644 test-tool/test_read10_dpofua.c delete mode 100644 test-tool/test_read10_flags.c create mode 100644 test-tool/test_read12_dpofua.c delete mode 100644 test-tool/test_read12_flags.c create mode 100644 test-tool/test_read16_dpofua.c delete mode 100644 test-tool/test_read16_flags.c create mode 100644 test-tool/test_verify10_dpo.c create mode 100644 test-tool/test_verify12_dpo.c create mode 100644 test-tool/test_verify16_dpo.c create mode 100644 test-tool/test_write10_dpofua.c create mode 100644 test-tool/test_write12_dpofua.c create mode 100644 test-tool/test_write16_dpofua.c create mode 100644 test-tool/test_writeverify10_dpo.c create mode 100644 test-tool/test_writeverify12_dpo.c create mode 100644 test-tool/test_writeverify16_dpo.c diff --git a/test-tool/Makefile.am b/test-tool/Makefile.am index defb3a4..1918b58 100644 --- a/test-tool/Makefile.am +++ b/test-tool/Makefile.am @@ -15,6 +15,7 @@ iscsi_test_cu_LDFLAGS = -ldl -lcunit iscsi_test_cu_SOURCES = iscsi-test-cu.c \ iscsi-support.c \ test_compareandwrite_simple.c \ + test_compareandwrite_dpofua.c \ test_compareandwrite_miscompare.c \ test_get_lba_status_simple.c \ test_get_lba_status_beyond_eol.c \ @@ -37,7 +38,7 @@ iscsi_test_cu_SOURCES = iscsi-test-cu.c \ test_orwrite_beyond_eol.c \ test_orwrite_0blocks.c \ test_orwrite_wrprotect.c \ - test_orwrite_flags.c \ + test_orwrite_dpofua.c \ test_orwrite_verify.c \ test_prefetch10_simple.c \ test_prefetch10_beyond_eol.c \ @@ -67,20 +68,20 @@ iscsi_test_cu_SOURCES = iscsi-test-cu.c \ test_read10_beyond_eol.c \ test_read10_0blocks.c \ test_read10_rdprotect.c \ - test_read10_flags.c \ + test_read10_dpofua.c \ test_read10_residuals.c \ test_read10_invalid.c \ test_read12_simple.c \ test_read12_beyond_eol.c \ test_read12_0blocks.c \ test_read12_rdprotect.c \ - test_read12_flags.c \ + test_read12_dpofua.c \ test_read12_residuals.c \ test_read16_simple.c \ test_read16_beyond_eol.c \ test_read16_0blocks.c \ test_read16_rdprotect.c \ - test_read16_flags.c \ + test_read16_dpofua.c \ test_read16_residuals.c \ test_readcapacity10_simple.c \ test_readcapacity16_alloclen.c \ @@ -121,6 +122,7 @@ iscsi_test_cu_SOURCES = iscsi-test-cu.c \ test_verify10_0blocks.c \ test_verify10_vrprotect.c \ test_verify10_flags.c \ + test_verify10_dpo.c \ test_verify10_mismatch.c \ test_verify10_mismatch_no_cmp.c \ test_verify12_simple.c \ @@ -128,6 +130,7 @@ iscsi_test_cu_SOURCES = iscsi-test-cu.c \ test_verify12_0blocks.c \ test_verify12_vrprotect.c \ test_verify12_flags.c \ + test_verify12_dpo.c \ test_verify12_mismatch.c \ test_verify12_mismatch_no_cmp.c \ test_verify16_simple.c \ @@ -135,25 +138,26 @@ iscsi_test_cu_SOURCES = iscsi-test-cu.c \ test_verify16_0blocks.c \ test_verify16_vrprotect.c \ test_verify16_flags.c \ + test_verify16_dpo.c \ test_verify16_mismatch.c \ test_verify16_mismatch_no_cmp.c \ test_write10_simple.c \ test_write10_beyond_eol.c \ test_write10_0blocks.c \ test_write10_wrprotect.c \ - test_write10_flags.c \ + test_write10_dpofua.c \ test_write10_residuals.c \ test_write12_simple.c \ test_write12_beyond_eol.c \ test_write12_0blocks.c \ test_write12_wrprotect.c \ - test_write12_flags.c \ + test_write12_dpofua.c \ test_write12_residuals.c \ test_write16_simple.c \ test_write16_beyond_eol.c \ test_write16_0blocks.c \ test_write16_wrprotect.c \ - test_write16_flags.c \ + test_write16_dpofua.c \ test_write16_residuals.c \ test_writesame10_simple.c \ test_writesame10_beyond_eol.c \ @@ -176,18 +180,21 @@ iscsi_test_cu_SOURCES = iscsi-test-cu.c \ test_writeverify10_0blocks.c \ test_writeverify10_wrprotect.c \ test_writeverify10_flags.c \ + test_writeverify10_dpo.c \ test_writeverify10_residuals.c \ test_writeverify12_simple.c \ test_writeverify12_beyond_eol.c \ test_writeverify12_0blocks.c \ test_writeverify12_wrprotect.c \ test_writeverify12_flags.c \ + test_writeverify12_dpo.c \ test_writeverify12_residuals.c \ test_writeverify16_simple.c \ test_writeverify16_beyond_eol.c \ test_writeverify16_0blocks.c \ test_writeverify16_wrprotect.c \ test_writeverify16_flags.c \ + test_writeverify16_dpo.c \ test_writeverify16_residuals.c endif diff --git a/test-tool/iscsi-test-cu.c b/test-tool/iscsi-test-cu.c index ce57f7f..acd9d8d 100644 --- a/test-tool/iscsi-test-cu.c +++ b/test-tool/iscsi-test-cu.c @@ -68,6 +68,7 @@ int (*real_iscsi_queue_pdu)(struct iscsi_context *iscsi, struct iscsi_pdu *pdu); *****************************************************************/ static CU_TestInfo tests_compareandwrite[] = { { (char *)"Simple", test_compareandwrite_simple }, + { (char *)"DpoFua", test_compareandwrite_dpofua }, { (char *)"Miscompare", test_compareandwrite_miscompare }, CU_TEST_INFO_NULL }; @@ -111,7 +112,7 @@ static CU_TestInfo tests_orwrite[] = { { (char *)"BeyondEol", test_orwrite_beyond_eol }, { (char *)"ZeroBlocks", test_orwrite_0blocks }, { (char *)"Protect", test_orwrite_wrprotect }, - { (char *)"Flags", test_orwrite_flags }, + { (char *)"DpoFua", test_orwrite_dpofua }, { (char *)"Verify", test_orwrite_verify }, CU_TEST_INFO_NULL }; @@ -200,7 +201,7 @@ static CU_TestInfo tests_read10[] = { { (char *)"BeyondEol", test_read10_beyond_eol }, { (char *)"ZeroBlocks", test_read10_0blocks }, { (char *)"ReadProtect", test_read10_rdprotect }, - { (char *)"Flags", test_read10_flags }, + { (char *)"DpoFua", test_read10_dpofua }, CU_TEST_INFO_NULL }; @@ -209,7 +210,7 @@ static CU_TestInfo tests_read12[] = { { (char *)"BeyondEol", test_read12_beyond_eol }, { (char *)"ZeroBlocks", test_read12_0blocks }, { (char *)"ReadProtect", test_read12_rdprotect }, - { (char *)"Flags", test_read12_flags }, + { (char *)"DpoFua", test_read12_dpofua }, CU_TEST_INFO_NULL }; @@ -218,7 +219,7 @@ static CU_TestInfo tests_read16[] = { { (char *)"BeyondEol", test_read16_beyond_eol }, { (char *)"ZeroBlocks", test_read16_0blocks }, { (char *)"ReadProtect", test_read16_rdprotect }, - { (char *)"Flags", test_read16_flags }, + { (char *)"DpoFua", test_read16_dpofua }, CU_TEST_INFO_NULL }; @@ -298,6 +299,7 @@ static CU_TestInfo tests_verify10[] = { { (char *)"ZeroBlocks", test_verify10_0blocks }, { (char *)"VerifyProtect", test_verify10_vrprotect }, { (char *)"Flags", test_verify10_flags }, + { (char *)"Dpo", test_verify10_dpo }, { (char *)"Mismatch", test_verify10_mismatch }, { (char *)"MismatchNoCmp", test_verify10_mismatch_no_cmp }, CU_TEST_INFO_NULL @@ -309,6 +311,7 @@ static CU_TestInfo tests_verify12[] = { { (char *)"ZeroBlocks", test_verify12_0blocks }, { (char *)"VerifyProtect", test_verify12_vrprotect }, { (char *)"Flags", test_verify12_flags }, + { (char *)"Dpo", test_verify12_dpo }, { (char *)"Mismatch", test_verify12_mismatch }, { (char *)"MismatchNoCmp", test_verify12_mismatch_no_cmp }, CU_TEST_INFO_NULL @@ -320,6 +323,7 @@ static CU_TestInfo tests_verify16[] = { { (char *)"ZeroBlocks", test_verify16_0blocks }, { (char *)"VerifyProtect", test_verify16_vrprotect }, { (char *)"Flags", test_verify16_flags }, + { (char *)"Dpo", test_verify16_dpo }, { (char *)"Mismatch", test_verify16_mismatch }, { (char *)"MismatchNoCmp", test_verify16_mismatch_no_cmp }, CU_TEST_INFO_NULL @@ -330,7 +334,7 @@ static CU_TestInfo tests_write10[] = { { (char *)"BeyondEol", test_write10_beyond_eol }, { (char *)"ZeroBlocks", test_write10_0blocks }, { (char *)"WriteProtect", test_write10_wrprotect }, - { (char *)"Flags", test_write10_flags }, + { (char *)"DpoFua", test_write10_dpofua }, CU_TEST_INFO_NULL }; @@ -339,7 +343,7 @@ static CU_TestInfo tests_write12[] = { { (char *)"BeyondEol", test_write12_beyond_eol }, { (char *)"ZeroBlocks", test_write12_0blocks }, { (char *)"WriteProtect", test_write12_wrprotect }, - { (char *)"Flags", test_write12_flags }, + { (char *)"DpoFua", test_write12_dpofua }, CU_TEST_INFO_NULL }; @@ -348,7 +352,7 @@ static CU_TestInfo tests_write16[] = { { (char *)"BeyondEol", test_write16_beyond_eol }, { (char *)"ZeroBlocks", test_write16_0blocks }, { (char *)"WriteProtect", test_write16_wrprotect }, - { (char *)"Flags", test_write16_flags }, + { (char *)"DpoFua", test_write16_dpofua }, CU_TEST_INFO_NULL }; @@ -382,6 +386,7 @@ static CU_TestInfo tests_writeverify10[] = { { (char *)"ZeroBlocks", test_writeverify10_0blocks }, { (char *)"WriteProtect", test_writeverify10_wrprotect }, { (char *)"Flags", test_writeverify10_flags }, + { (char *)"Dpo", test_writeverify10_dpo }, CU_TEST_INFO_NULL }; @@ -391,6 +396,7 @@ static CU_TestInfo tests_writeverify12[] = { { (char *)"ZeroBlocks", test_writeverify12_0blocks }, { (char *)"WriteProtect", test_writeverify12_wrprotect }, { (char *)"Flags", test_writeverify12_flags }, + { (char *)"Dpo", test_writeverify12_dpo }, CU_TEST_INFO_NULL }; @@ -400,6 +406,7 @@ static CU_TestInfo tests_writeverify16[] = { { (char *)"ZeroBlocks", test_writeverify16_0blocks }, { (char *)"WriteProtect", test_writeverify16_wrprotect }, { (char *)"Flags", test_writeverify16_flags }, + { (char *)"Dpo", test_writeverify16_dpo }, CU_TEST_INFO_NULL }; diff --git a/test-tool/iscsi-test-cu.h b/test-tool/iscsi-test-cu.h index cd82f74..8a95e5d 100644 --- a/test-tool/iscsi-test-cu.h +++ b/test-tool/iscsi-test-cu.h @@ -49,6 +49,7 @@ void test_setup(void); void test_teardown(void); void test_compareandwrite_simple(void); +void test_compareandwrite_dpofua(void); void test_compareandwrite_miscompare(void); void test_get_lba_status_simple(void); @@ -79,7 +80,7 @@ void test_orwrite_simple(void); void test_orwrite_beyond_eol(void); void test_orwrite_0blocks(void); void test_orwrite_wrprotect(void); -void test_orwrite_flags(void); +void test_orwrite_dpofua(void); void test_orwrite_verify(void); void test_prefetch10_simple(void); @@ -128,7 +129,7 @@ void test_read10_simple(void); void test_read10_beyond_eol(void); void test_read10_0blocks(void); void test_read10_rdprotect(void); -void test_read10_flags(void); +void test_read10_dpofua(void); void test_read10_residuals(void); void test_read10_invalid(void); @@ -136,14 +137,14 @@ void test_read12_simple(void); void test_read12_beyond_eol(void); void test_read12_0blocks(void); void test_read12_rdprotect(void); -void test_read12_flags(void); +void test_read12_dpofua(void); void test_read12_residuals(void); void test_read16_simple(void); void test_read16_beyond_eol(void); void test_read16_0blocks(void); void test_read16_rdprotect(void); -void test_read16_flags(void); +void test_read16_dpofua(void); void test_read16_residuals(void); void test_readcapacity10_simple(void); @@ -194,6 +195,7 @@ void test_verify10_beyond_eol(void); void test_verify10_0blocks(void); void test_verify10_vrprotect(void); void test_verify10_flags(void); +void test_verify10_dpo(void); void test_verify10_mismatch(void); void test_verify10_mismatch_no_cmp(void); @@ -202,6 +204,7 @@ void test_verify12_beyond_eol(void); void test_verify12_0blocks(void); void test_verify12_vrprotect(void); void test_verify12_flags(void); +void test_verify12_dpo(void); void test_verify12_mismatch(void); void test_verify12_mismatch_no_cmp(void); @@ -210,6 +213,7 @@ void test_verify16_beyond_eol(void); void test_verify16_0blocks(void); void test_verify16_vrprotect(void); void test_verify16_flags(void); +void test_verify16_dpo(void); void test_verify16_mismatch(void); void test_verify16_mismatch_no_cmp(void); @@ -217,21 +221,21 @@ void test_write10_simple(void); void test_write10_beyond_eol(void); void test_write10_0blocks(void); void test_write10_wrprotect(void); -void test_write10_flags(void); +void test_write10_dpofua(void); void test_write10_residuals(void); void test_write12_simple(void); void test_write12_beyond_eol(void); void test_write12_0blocks(void); void test_write12_wrprotect(void); -void test_write12_flags(void); +void test_write12_dpofua(void); void test_write12_residuals(void); void test_write16_simple(void); void test_write16_beyond_eol(void); void test_write16_0blocks(void); void test_write16_wrprotect(void); -void test_write16_flags(void); +void test_write16_dpofua(void); void test_write16_residuals(void); void test_writesame10_simple(void); @@ -257,6 +261,7 @@ void test_writeverify10_beyond_eol(void); void test_writeverify10_0blocks(void); void test_writeverify10_wrprotect(void); void test_writeverify10_flags(void); +void test_writeverify10_dpo(void); void test_writeverify10_residuals(void); void test_writeverify12_simple(void); @@ -264,6 +269,7 @@ void test_writeverify12_beyond_eol(void); void test_writeverify12_0blocks(void); void test_writeverify12_wrprotect(void); void test_writeverify12_flags(void); +void test_writeverify12_dpo(void); void test_writeverify12_residuals(void); void test_writeverify16_simple(void); @@ -271,6 +277,7 @@ void test_writeverify16_beyond_eol(void); void test_writeverify16_0blocks(void); void test_writeverify16_wrprotect(void); void test_writeverify16_flags(void); +void test_writeverify16_dpo(void); void test_writeverify16_residuals(void); #endif /* _ISCSI_TEST_CU_H_ */ diff --git a/test-tool/test_compareandwrite_dpofua.c b/test-tool/test_compareandwrite_dpofua.c new file mode 100644 index 0000000..0adc802 --- /dev/null +++ b/test-tool/test_compareandwrite_dpofua.c @@ -0,0 +1,127 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_compareandwrite_dpofua(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test COMPAREANDWRITE DPO/FUA flags"); + + CHECK_FOR_SBC; + CHECK_FOR_DATALOSS; + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test COMPAREANDWRITE with DPO==1"); + if (dpofua) { + ret = compareandwrite(sd, 0, buf, block_size, + block_size, 0, 1, 0, 0, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = compareandwrite(sd, 0, buf, block_size, + block_size, 0, 1, 0, 0, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test COMPAREANDWRITE with FUA==1"); + if (dpofua) { + ret = compareandwrite(sd, 0, buf, block_size, + block_size, 0, 0, 1, 0, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = compareandwrite(sd, 0, buf, block_size, + block_size, 0, 0, 1, 0, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test COMPAREANDWRITE with DPO==1 FUA==1"); + if (dpofua) { + ret = compareandwrite(sd, 0, buf, block_size, + block_size, 0, 1, 1, 0, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = compareandwrite(sd, 0, buf, block_size, + block_size, 0, 1, 1, 0, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for COMPAREANDWRITE"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_COMPARE_AND_WRITE, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO/FUA flags " + "are set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x18); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO/FUA " + "flags are clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_orwrite_dpofua.c b/test-tool/test_orwrite_dpofua.c new file mode 100644 index 0000000..901d143 --- /dev/null +++ b/test-tool/test_orwrite_dpofua.c @@ -0,0 +1,137 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_orwrite_dpofua(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test ORWRITE DPO/FUA flags"); + + CHECK_FOR_SBC; + CHECK_FOR_DATALOSS; + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test ORWRITE with DPO==1"); + if (dpofua) { + ret = orwrite(sd, 0, block_size, + block_size, 0, 1, 0, 0, 0, buf, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] ORWRITE is not implemented."); + CU_PASS("ORWRITE is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = orwrite(sd, 0, block_size, + block_size, 0, 1, 0, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] ORWRITE is not implemented."); + CU_PASS("ORWRITE is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test ORWRITE with FUA==1"); + if (dpofua) { + ret = orwrite(sd, 0, block_size, + block_size, 0, 0, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = orwrite(sd, 0, block_size, + block_size, 0, 0, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test ORWRITE with DPO==1 FUA==1"); + if (dpofua) { + ret = orwrite(sd, 0, block_size, + block_size, 0, 1, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = orwrite(sd, 0, block_size, + block_size, 0, 1, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for ORWRITE"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_ORWRITE, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO/FUA flags " + "are set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x18); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO/FUA " + "flags are clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_orwrite_flags.c b/test-tool/test_orwrite_flags.c deleted file mode 100644 index 3af9aa1..0000000 --- a/test-tool/test_orwrite_flags.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (C) 2013 Ronnie Sahlberg - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . -*/ - -#include -#include -#include -#include - -#include - -#include "iscsi.h" -#include "scsi-lowlevel.h" -#include "iscsi-test-cu.h" - -void -test_orwrite_flags(void) -{ - int ret; - unsigned char *buf = alloca(block_size); - - CHECK_FOR_DATALOSS; - CHECK_FOR_SBC; - - logging(LOG_VERBOSE, LOG_BLANK_LINE); - logging(LOG_VERBOSE, "Test ORWRITE flags"); - - logging(LOG_VERBOSE, "Test ORWRITE with DPO==1"); - ret = orwrite(sd, 0, - block_size, block_size, 0, 1, 0, 0, 0, buf, - EXPECT_STATUS_GOOD); - if (ret == -2) { - CU_PASS("[SKIPPED] Target does not support VERIFY16. Skipping test"); - return; - } - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test ORWRITE with FUA==1 FUA_NV==0"); - ret = orwrite(sd, 0, - block_size, block_size, 0, 0, 1, 0, 0, buf, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test ORWRITE with FUA==1 FUA_NV==1"); - ret = orwrite(sd, 0, - block_size, block_size, 0, 0, 1, 1, 0, buf, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test ORWRITE with FUA==0 FUA_NV==1"); - ret = orwrite(sd, 0, - block_size, block_size, 0, 0, 0, 1, 0, buf, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test ORWRITE with DPO==1 FUA==1 FUA_NV==1"); - ret = orwrite(sd, 0, - block_size, block_size, 0, 1, 1, 1, 0, buf, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); -} diff --git a/test-tool/test_read10_dpofua.c b/test-tool/test_read10_dpofua.c new file mode 100644 index 0000000..8c005e0 --- /dev/null +++ b/test-tool/test_read10_dpofua.c @@ -0,0 +1,126 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_read10_dpofua(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test READ10 DPO/FUA flags"); + + CHECK_FOR_SBC; + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test READ10 with DPO==1"); + if (dpofua) { + ret = read10(sd, NULL, 0, + block_size, block_size, 0, 1, 0, 0, 0, NULL, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = read10(sd, NULL, 0, + block_size, block_size, 0, 1, 0, 0, 0, NULL, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test READ10 with FUA==1"); + if (dpofua) { + ret = read10(sd, NULL, 0, + block_size, block_size, 0, 0, 1, 0, 0, NULL, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = read10(sd, NULL, 0, + block_size, block_size, 0, 0, 1, 0, 0, NULL, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test READ10 with DPO==1 FUA==1"); + if (dpofua) { + ret = read10(sd, NULL, 0, + block_size, block_size, 0, 1, 1, 0, 0, NULL, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = read10(sd, NULL, 0, + block_size, block_size, 0, 1, 1, 0, 0, NULL, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for READ10"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_READ10, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO/FUA flags " + "are set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x18); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO/FUA " + "flags are clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_read10_flags.c b/test-tool/test_read10_flags.c deleted file mode 100644 index 2814ae9..0000000 --- a/test-tool/test_read10_flags.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2012 by Lee Duncan - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . -*/ - -#include -#include -#include - -#include - -#include "iscsi.h" -#include "scsi-lowlevel.h" -#include "iscsi-test-cu.h" - -void -test_read10_flags(void) -{ - int ret; - - logging(LOG_VERBOSE, LOG_BLANK_LINE); - logging(LOG_VERBOSE, "Test READ10 flags"); - - CHECK_FOR_SBC; - - logging(LOG_VERBOSE, "Test READ10 with DPO==1"); - ret = read10(sd, NULL, 0, - block_size, block_size, 0, 1, 0, 0, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ10 with FUA==1 FUA_NV==0"); - ret = read10(sd, NULL, 0, - block_size, block_size, 0, 0, 1, 0, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ10 with FUA==1 FUA_NV==1"); - ret = read10(sd, NULL, 0, - block_size, block_size, 0, 0, 1, 1, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ10 with FUA==0 FUA_NV==1"); - ret = read10(sd, NULL, 0, - block_size, block_size, 0, 0, 0, 1, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ10 with DPO==1 FUA==1 FUA_NV==1"); - ret = read10(sd, NULL, 0, - block_size, block_size, 0, 1, 1, 1, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); -} diff --git a/test-tool/test_read12_dpofua.c b/test-tool/test_read12_dpofua.c new file mode 100644 index 0000000..d964061 --- /dev/null +++ b/test-tool/test_read12_dpofua.c @@ -0,0 +1,125 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_read12_dpofua(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test READ12 DPO/FUA flags"); + + CHECK_FOR_SBC; + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test READ12 with DPO==1"); + if (dpofua) { + ret = read12(sd, 0, + block_size, block_size, 0, 1, 0, 0, 0, NULL, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = read12(sd, 0, + block_size, block_size, 0, 1, 0, 0, 0, NULL, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test READ12 with FUA==1"); + if (dpofua) { + ret = read12(sd, 0, + block_size, block_size, 0, 0, 1, 0, 0, NULL, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = read12(sd, 0, + block_size, block_size, 0, 0, 1, 0, 0, NULL, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test READ12 with DPO==1 FUA==1"); + if (dpofua) { + ret = read12(sd, 0, + block_size, block_size, 0, 1, 1, 0, 0, NULL, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = read12(sd, 0, + block_size, block_size, 0, 1, 1, 0, 0, NULL, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for READ12"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_READ12, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO/FUA flags " + "are set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x18); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO/FUA " + "flags are clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_read12_flags.c b/test-tool/test_read12_flags.c deleted file mode 100644 index 095b6b9..0000000 --- a/test-tool/test_read12_flags.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 2013 Ronnie Sahlberg - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . -*/ - -#include -#include -#include - -#include - -#include "iscsi.h" -#include "scsi-lowlevel.h" -#include "iscsi-test-cu.h" - -void -test_read12_flags(void) -{ - int ret; - - logging(LOG_VERBOSE, LOG_BLANK_LINE); - logging(LOG_VERBOSE, "Test READ12 flags"); - - CHECK_FOR_SBC; - - logging(LOG_VERBOSE, "Test READ12 with DPO==1"); - ret = read12(sd, 0, - block_size, block_size, 0, 1, 0, 0, 0, NULL, - EXPECT_STATUS_GOOD); - if (ret == -2) { - logging(LOG_NORMAL, "[SKIPPED] READ12 is not implemented."); - CU_PASS("READ12 is not implemented."); - return; - } - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ12 with FUA==1 FUA_NV==0"); - ret = read12(sd, 0, - block_size, block_size, 0, 0, 1, 0, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ12 with FUA==1 FUA_NV==1"); - ret = read12(sd, 0, - block_size, block_size, 0, 0, 1, 1, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ12 with FUA==0 FUA_NV==1"); - ret = read12(sd, 0, - block_size, block_size, 0, 0, 0, 1, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ12 with DPO==1 FUA==1 FUA_NV==1"); - ret = read12(sd, 0, - block_size, block_size, 0, 1, 1, 1, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); -} diff --git a/test-tool/test_read16_dpofua.c b/test-tool/test_read16_dpofua.c new file mode 100644 index 0000000..906a484 --- /dev/null +++ b/test-tool/test_read16_dpofua.c @@ -0,0 +1,126 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_read16_dpofua(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test READ16 DPO/FUA flags"); + + CHECK_FOR_SBC; + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test READ16 with DPO==1"); + if (dpofua) { + ret = read16(sd, 0, + block_size, block_size, 0, 1, 0, 0, 0, NULL, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = read16(sd, 0, + block_size, block_size, 0, 1, 0, 0, 0, NULL, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test READ16 with FUA==1"); + if (dpofua) { + ret = read16(sd, 0, + block_size, block_size, 0, 0, 1, 0, 0, NULL, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = read16(sd, 0, + block_size, block_size, 0, 0, 1, 0, 0, NULL, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test READ16 with DPO==1 FUA==1"); + if (dpofua) { + ret = read16(sd, 0, + block_size, block_size, 0, 1, 1, 0, 0, NULL, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = read16(sd, 0, + block_size, block_size, 0, 1, 1, 0, 0, NULL, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for READ16"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_READ16, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO/FUA flags " + "are set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x18); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO/FUA " + "flags are clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_read16_flags.c b/test-tool/test_read16_flags.c deleted file mode 100644 index 6f355f5..0000000 --- a/test-tool/test_read16_flags.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 2013 Ronnie Sahlberg - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . -*/ - -#include -#include -#include - -#include - -#include "iscsi.h" -#include "scsi-lowlevel.h" -#include "iscsi-test-cu.h" - -void -test_read16_flags(void) -{ - int ret; - - CHECK_FOR_SBC; - - logging(LOG_VERBOSE, LOG_BLANK_LINE); - logging(LOG_VERBOSE, "Test READ16 flags"); - - logging(LOG_VERBOSE, "Test READ16 with DPO==1"); - ret = read16(sd, 0, - block_size, block_size, 0, 1, 0, 0, 0, NULL, - EXPECT_STATUS_GOOD); - if (ret == -2) { - logging(LOG_NORMAL, "[SKIPPED] READ16 is not implemented on this target and it does not claim SBC-3 support."); - CU_PASS("READ16 is not implemented and no SBC-3 support claimed."); - return; - } - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ16 with FUA==1 FUA_NV==0"); - ret = read16(sd, 0, - block_size, block_size, 0, 0, 1, 0, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ16 with FUA==1 FUA_NV==1"); - ret = read16(sd, 0, - block_size, block_size, 0, 0, 1, 1, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ16 with FUA==0 FUA_NV==1"); - ret = read16(sd, 0, - block_size, block_size, 0, 0, 0, 1, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test READ16 with DPO==1 FUA==1 FUA_NV==1"); - ret = read16(sd, 0, - block_size, block_size, 0, 1, 1, 1, 0, NULL, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); -} diff --git a/test-tool/test_verify10_dpo.c b/test-tool/test_verify10_dpo.c new file mode 100644 index 0000000..39d9aaa --- /dev/null +++ b/test-tool/test_verify10_dpo.c @@ -0,0 +1,115 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_verify10_dpo(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test VERIFY10 DPO flag"); + + CHECK_FOR_SBC; + + ret = read10(sd, NULL, 0, block_size, + block_size, 0, 0, 0, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test VERIFY10 with DPO==1"); + if (dpofua) { + ret = verify10(sd, 0, block_size, + block_size, 0, 1, 0, buf, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] VERIFY10 is not implemented."); + CU_PASS("VERIFY10 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = verify10(sd, 0, block_size, + block_size, 0, 1, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] VERIFY10 is not implemented."); + CU_PASS("VERIFY10 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for VERIFY10"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_VERIFY10, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO flag " + "is set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x10); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO " + "flag is clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_verify10_flags.c b/test-tool/test_verify10_flags.c index 5bb109f..c88e52c 100644 --- a/test-tool/test_verify10_flags.c +++ b/test-tool/test_verify10_flags.c @@ -40,9 +40,9 @@ test_verify10_flags(void) CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test VERIFY10 with DPO==1"); + logging(LOG_VERBOSE, "Test VERIFY10 with BYTCHK==1"); ret = verify10(sd, 0, block_size, - block_size, 0, 1, 0, buf, + block_size, 0, 0, 1, buf, EXPECT_STATUS_GOOD); if (ret == -2) { logging(LOG_NORMAL, "[SKIPPED] VERIFY10 is not implemented."); @@ -51,12 +51,5 @@ test_verify10_flags(void) return; } CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test VERIFY10 with BYTCHK==1"); - ret = verify10(sd, 0, block_size, - block_size, 0, 0, 1, buf, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); free(buf); } diff --git a/test-tool/test_verify12_dpo.c b/test-tool/test_verify12_dpo.c new file mode 100644 index 0000000..b8f5296 --- /dev/null +++ b/test-tool/test_verify12_dpo.c @@ -0,0 +1,115 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_verify12_dpo(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test VERIFY12 DPO flag"); + + CHECK_FOR_SBC; + + ret = read10(sd, NULL, 0, block_size, + block_size, 0, 0, 0, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test VERIFY12 with DPO==1"); + if (dpofua) { + ret = verify12(sd, 0, block_size, + block_size, 0, 1, 0, buf, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] VERIFY12 is not implemented."); + CU_PASS("VERIFY12 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = verify12(sd, 0, block_size, + block_size, 0, 1, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] VERIFY12 is not implemented."); + CU_PASS("VERIFY12 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for VERIFY12"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_VERIFY12, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO flag " + "is set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x10); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO " + "flag is clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_verify12_flags.c b/test-tool/test_verify12_flags.c index 6c1900a..8cff3cf 100644 --- a/test-tool/test_verify12_flags.c +++ b/test-tool/test_verify12_flags.c @@ -41,9 +41,9 @@ test_verify12_flags(void) CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test VERIFY12 with DPO==1"); + logging(LOG_VERBOSE, "Test VERIFY12 with BYTCHK==1"); ret = verify12(sd, 0, block_size, - block_size, 0, 1, 0, buf, + block_size, 0, 0, 1, buf, EXPECT_STATUS_GOOD); if (ret == -2) { logging(LOG_NORMAL, "[SKIPPED] VERIFY12 is not implemented."); @@ -51,11 +51,4 @@ test_verify12_flags(void) return; } CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test VERIFY12 with BYTCHK==1"); - ret = verify12(sd, 0, block_size, - block_size, 0, 0, 1, buf, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); } diff --git a/test-tool/test_verify16_dpo.c b/test-tool/test_verify16_dpo.c new file mode 100644 index 0000000..9e68830 --- /dev/null +++ b/test-tool/test_verify16_dpo.c @@ -0,0 +1,115 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_verify16_dpo(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test VERIFY16 DPO flag"); + + CHECK_FOR_SBC; + + ret = read10(sd, NULL, 0, block_size, + block_size, 0, 0, 0, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test VERIFY16 with DPO==1"); + if (dpofua) { + ret = verify16(sd, 0, block_size, + block_size, 0, 1, 0, buf, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] VERIFY16 is not implemented."); + CU_PASS("VERIFY16 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = verify16(sd, 0, block_size, + block_size, 0, 1, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] VERIFY16 is not implemented."); + CU_PASS("VERIFY16 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for VERIFY16"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_VERIFY16, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO flag " + "is set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x10); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO " + "flag is clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_verify16_flags.c b/test-tool/test_verify16_flags.c index a91608a..55cb6f6 100644 --- a/test-tool/test_verify16_flags.c +++ b/test-tool/test_verify16_flags.c @@ -39,9 +39,10 @@ test_verify16_flags(void) block_size, 0, 0, 0, 0, 0, buf, EXPECT_STATUS_GOOD); - logging(LOG_VERBOSE, "Test VERIFY16 with DPO==1"); + + logging(LOG_VERBOSE, "Test VERIFY16 with BYTCHK==1"); ret = verify16(sd, 0, block_size, - block_size, 0, 1, 0, buf, + block_size, 0, 0, 1, buf, EXPECT_STATUS_GOOD); if (ret == -2) { logging(LOG_NORMAL, "[SKIPPED] VERIFY16 is not implemented."); @@ -49,11 +50,4 @@ test_verify16_flags(void) return; } CU_ASSERT_EQUAL(ret, 0); - - - logging(LOG_VERBOSE, "Test VERIFY16 with BYTCHK==1"); - ret = verify16(sd, 0, block_size, - block_size, 0, 0, 1, buf, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); } diff --git a/test-tool/test_write10_dpofua.c b/test-tool/test_write10_dpofua.c new file mode 100644 index 0000000..3eac700 --- /dev/null +++ b/test-tool/test_write10_dpofua.c @@ -0,0 +1,128 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_write10_dpofua(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test WRITE10 DPO/FUA flags"); + + CHECK_FOR_SBC; + CHECK_FOR_DATALOSS; + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test WRITE10 with DPO==1"); + if (dpofua) { + ret = write10(sd, 0, block_size, + block_size, 0, 1, 0, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = write10(sd, 0, block_size, + block_size, 0, 1, 0, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test WRITE10 with FUA==1"); + if (dpofua) { + ret = write10(sd, 0, block_size, + block_size, 0, 0, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = write10(sd, 0, block_size, + block_size, 0, 0, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test WRITE10 with DPO==1 FUA==1"); + if (dpofua) { + ret = write10(sd, 0, block_size, + block_size, 0, 1, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = write10(sd, 0, block_size, + block_size, 0, 1, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for WRITE10"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_WRITE10, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO/FUA flags " + "are set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x18); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO/FUA " + "flags are clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_write12_dpofua.c b/test-tool/test_write12_dpofua.c new file mode 100644 index 0000000..15ea187 --- /dev/null +++ b/test-tool/test_write12_dpofua.c @@ -0,0 +1,138 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_write12_dpofua(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test WRITE12 DPO/FUA flags"); + + CHECK_FOR_SBC; + CHECK_FOR_DATALOSS; + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test WRITE12 with DPO==1"); + if (dpofua) { + ret = write12(sd, 0, block_size, + block_size, 0, 1, 0, 0, 0, buf, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] WRITE12 is not implemented."); + CU_PASS("WRITE12 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = write12(sd, 0, block_size, + block_size, 0, 1, 0, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] WRITE12 is not implemented."); + CU_PASS("WRITE12 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test WRITE12 with FUA==1"); + if (dpofua) { + ret = write12(sd, 0, block_size, + block_size, 0, 0, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = write12(sd, 0, block_size, + block_size, 0, 0, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test WRITE12 with DPO==1 FUA==1"); + if (dpofua) { + ret = write12(sd, 0, block_size, + block_size, 0, 1, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = write12(sd, 0, block_size, + block_size, 0, 1, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for WRITE12"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_WRITE12, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO/FUA flags " + "are set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x18); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO/FUA " + "flags are clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_write16_dpofua.c b/test-tool/test_write16_dpofua.c new file mode 100644 index 0000000..396e253 --- /dev/null +++ b/test-tool/test_write16_dpofua.c @@ -0,0 +1,138 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_write16_dpofua(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test WRITE16 DPO/FUA flags"); + + CHECK_FOR_SBC; + CHECK_FOR_DATALOSS; + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test WRITE16 with DPO==1"); + if (dpofua) { + ret = write16(sd, 0, block_size, + block_size, 0, 1, 0, 0, 0, buf, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] WRITE16 is not implemented."); + CU_PASS("WRITE16 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = write16(sd, 0, block_size, + block_size, 0, 1, 0, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] WRITE16 is not implemented."); + CU_PASS("WRITE16 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test WRITE16 with FUA==1"); + if (dpofua) { + ret = write16(sd, 0, block_size, + block_size, 0, 0, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = write16(sd, 0, block_size, + block_size, 0, 0, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test WRITE16 with DPO==1 FUA==1"); + if (dpofua) { + ret = write16(sd, 0, block_size, + block_size, 0, 1, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = write16(sd, 0, block_size, + block_size, 0, 1, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + CU_ASSERT_EQUAL(ret, 0); + } + + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for WRITE16"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_WRITE16, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO/FUA flags " + "are set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x18); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO/FUA " + "flags are clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x18, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_writeverify10_dpo.c b/test-tool/test_writeverify10_dpo.c new file mode 100644 index 0000000..eb2a140 --- /dev/null +++ b/test-tool/test_writeverify10_dpo.c @@ -0,0 +1,115 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_writeverify10_dpo(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test WRITEVERIFY10 DPO flag"); + + CHECK_FOR_SBC; + + ret = read10(sd, NULL, 0, block_size, + block_size, 0, 0, 0, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test WRITEVERIFY10 with DPO==1"); + if (dpofua) { + ret = writeverify10(sd, 0, block_size, + block_size, 0, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY10 is not implemented."); + CU_PASS("WRITEVERIFY10 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = writeverify10(sd, 0, block_size, + block_size, 0, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY10 is not implemented."); + CU_PASS("WRITEVERIFY10 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for WRITEVERIFY10"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_WRITE_VERIFY10, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO flag " + "is set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x10); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO " + "flag is clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_writeverify10_flags.c b/test-tool/test_writeverify10_flags.c index 2461cbe..6af3919 100644 --- a/test-tool/test_writeverify10_flags.c +++ b/test-tool/test_writeverify10_flags.c @@ -37,9 +37,10 @@ test_writeverify10_flags(void) logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, "Test WRITEVERIFY10 flags"); - logging(LOG_VERBOSE, "Test WRITEVERIFY10 with DPO==1"); + + logging(LOG_VERBOSE, "Test WRITEVERIFY10 with BYTCHK==1"); ret = writeverify10(sd, 0, - block_size, block_size, 0, 1, 0, 0, buf, + block_size, block_size, 0, 0, 1, 0, buf, EXPECT_STATUS_GOOD); if (ret == -2) { logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY10 is not implemented."); @@ -47,10 +48,4 @@ test_writeverify10_flags(void) return; } CU_ASSERT_EQUAL(ret, 0); - - logging(LOG_VERBOSE, "Test WRITEVERIFY10 with BYTCHK==1"); - ret = writeverify10(sd, 0, - block_size, block_size, 0, 0, 1, 0, buf, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); } diff --git a/test-tool/test_writeverify12_dpo.c b/test-tool/test_writeverify12_dpo.c new file mode 100644 index 0000000..bc3a7b1 --- /dev/null +++ b/test-tool/test_writeverify12_dpo.c @@ -0,0 +1,115 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_writeverify12_dpo(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test WRITEVERIFY12 DPO flag"); + + CHECK_FOR_SBC; + + ret = read10(sd, NULL, 0, block_size, + block_size, 0, 0, 0, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test WRITEVERIFY12 with DPO==1"); + if (dpofua) { + ret = writeverify12(sd, 0, block_size, + block_size, 0, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY12 is not implemented."); + CU_PASS("WRITEVERIFY12 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = writeverify12(sd, 0, block_size, + block_size, 0, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY12 is not implemented."); + CU_PASS("WRITEVERIFY12 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for WRITEVERIFY12"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_WRITE_VERIFY12, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO flag " + "is set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x10); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO " + "flag is clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_writeverify12_flags.c b/test-tool/test_writeverify12_flags.c index a894e29..a47e7c9 100644 --- a/test-tool/test_writeverify12_flags.c +++ b/test-tool/test_writeverify12_flags.c @@ -37,9 +37,10 @@ test_writeverify12_flags(void) logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, "Test WRITEVERIFY12 flags"); - logging(LOG_VERBOSE, "Test WRITEVERIFY12 with DPO==1"); + + logging(LOG_VERBOSE, "Test WRITEVERIFY12 with BYTCHK==1"); ret = writeverify12(sd, 0, - block_size, block_size, 0, 1, 0, 0, buf, + block_size, block_size, 0, 0, 1, 0, buf, EXPECT_STATUS_GOOD); if (ret == -2) { logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY12 is not implemented."); @@ -47,10 +48,4 @@ test_writeverify12_flags(void) return; } CU_ASSERT_EQUAL(ret, 0); - - logging(LOG_VERBOSE, "Test WRITEVERIFY12 with BYTCHK==1"); - ret = writeverify12(sd, 0, - block_size, block_size, 0, 0, 1, 0, buf, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); } diff --git a/test-tool/test_writeverify16_dpo.c b/test-tool/test_writeverify16_dpo.c new file mode 100644 index 0000000..b439f2b --- /dev/null +++ b/test-tool/test_writeverify16_dpo.c @@ -0,0 +1,116 @@ +/* + Copyright (C) 2014 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_writeverify16_dpo(void) +{ + int ret, dpofua; + struct scsi_task *ms_task = NULL; + struct scsi_mode_sense *ms; + struct scsi_task *rso_task = NULL; + struct scsi_report_supported_op_codes_one_command *rsoc; + unsigned char *buf = alloca(block_size); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test WRITEVERIFY16 DPO flag"); + + CHECK_FOR_SBC; + + ret = read10(sd, NULL, 0, block_size, + block_size, 0, 0, 0, 0, 0, buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); + ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, + SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); + ms = scsi_datain_unmarshall(ms_task); + dpofua = !!(ms->device_specific_parameter & 0x10); + scsi_free_scsi_task(ms_task); + + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " + "DPO/FUA flags in CDBs"); + } else { + logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " + "CDBs with DPO/FUA set"); + } + + logging(LOG_VERBOSE, "Test WRITEVERIFY16 with DPO==1"); + if (dpofua) { + ret = writeverify16(sd, 0, block_size, + block_size, 0, 1, 0, 0, buf, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY16 is not implemented."); + CU_PASS("WRITEVERIFY16 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } else { + ret = writeverify16(sd, 0, block_size, + block_size, 0, 1, 0, 0, buf, + EXPECT_INVALID_FIELD_IN_CDB); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY16 is not implemented."); + CU_PASS("WRITEVERIFY16 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + } + + + logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " + "for WRITEVERIFY16"); + ret = report_supported_opcodes(sd, &rso_task, + 0, SCSI_REPORT_SUPPORTING_OPCODE, + SCSI_OPCODE_WRITE_VERIFY16, + 0, + 65535, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. " + "Skipping this part of the test"); + return; + } + logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); + rsoc = scsi_datain_unmarshall(rso_task); + CU_ASSERT_NOT_EQUAL(rsoc, NULL); + if (dpofua) { + logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO flag " + "is set in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x10); + } else { + logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO " + "flag is clear in the CDB_USAGE_DATA"); + CU_ASSERT_EQUAL(rsoc->cdb_usage_data[1] & 0x10, 0x00); + } + scsi_free_scsi_task(rso_task); +} diff --git a/test-tool/test_writeverify16_flags.c b/test-tool/test_writeverify16_flags.c index 911a417..722252a 100644 --- a/test-tool/test_writeverify16_flags.c +++ b/test-tool/test_writeverify16_flags.c @@ -37,9 +37,10 @@ test_writeverify16_flags(void) logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, "Test WRITEVERIFY16 flags"); - logging(LOG_VERBOSE, "Test WRITEVERIFY16 with DPO==1"); + + logging(LOG_VERBOSE, "Test WRITEVERIFY16 with BYTCHK==1"); ret = writeverify16(sd, 0, - block_size, block_size, 0, 1, 0, 0, buf, + block_size, block_size, 0, 0, 1, 0, buf, EXPECT_STATUS_GOOD); if (ret == -2) { logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY16 is not implemented."); @@ -47,10 +48,4 @@ test_writeverify16_flags(void) return; } CU_ASSERT_EQUAL(ret, 0); - - logging(LOG_VERBOSE, "Test WRITEVERIFY16 with BYTCHK==1"); - ret = writeverify16(sd, 0, - block_size, block_size, 0, 0, 1, 0, buf, - EXPECT_STATUS_GOOD); - CU_ASSERT_EQUAL(ret, 0); }