示例#1
0
void
test_orwrite_dpofua(void)
{ 
        int dpofua, usage_data_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 ORWRITE DPO/FUA flags");

        CHECK_FOR_SBC;
        CHECK_FOR_DATALOSS;

        logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
        MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
                   SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
                   EXPECT_STATUS_GOOD);

        logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
        ms = scsi_datain_unmarshall(ms_task);
        dpofua = ms && (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");
        memset(scratch, 0xa6, block_size);
        if (dpofua) {
                ORWRITE(sd, 0, block_size, block_size, 0, 1, 0, 0, 0, scratch,
                        EXPECT_STATUS_GOOD);
        } else {
                ORWRITE(sd, 0, block_size, block_size, 0, 1, 0, 0, 0, scratch,
                        EXPECT_INVALID_FIELD_IN_CDB);
        }

        logging(LOG_VERBOSE, "Test ORWRITE with FUA==1");
        if (dpofua) {
                ORWRITE(sd, 0, block_size, block_size, 0, 0, 1, 0, 0, scratch,
                        EXPECT_STATUS_GOOD);
        } else {
                ORWRITE(sd, 0, block_size, block_size, 0, 0, 1, 0, 0, scratch,
                        EXPECT_INVALID_FIELD_IN_CDB);
        }

        logging(LOG_VERBOSE, "Test ORWRITE with DPO==1 FUA==1");
        if (dpofua) {
                ORWRITE(sd, 0, block_size, block_size, 0, 1, 1, 0, 0, scratch,
                        EXPECT_STATUS_GOOD);
        } else {
                ORWRITE(sd, 0, block_size, block_size, 0, 1, 1, 0, 0, scratch,
                        EXPECT_INVALID_FIELD_IN_CDB);
        }

        logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
                "for ORWRITE");
        REPORT_SUPPORTED_OPCODES(sd, &rso_task,
                                 0, SCSI_REPORT_SUPPORTING_OPCODE,
                                 SCSI_OPCODE_ORWRITE,
                                 0,
                                 65535,
                                 EXPECT_STATUS_GOOD);
        logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
        rsoc = scsi_datain_unmarshall(rso_task);
        CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc);
        
        usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18;
        if (dpofua) {
                logging(LOG_VERBOSE, "DPOFUA is set. Verify the "
                        "DPO/FUA flags are set in the CDB_USAGE_DATA");
                if (!usage_data_dpofua) {
                        logging(LOG_NORMAL, "[FAILED] DpoFua not set "
                                "in CDB_USAGE_DATE");
                        CU_FAIL("DpoFua not set in CDB_USAGE_DATE");
                }
        } else {
                logging(LOG_VERBOSE, "DPOFUA is clear. Verify the "
                        "DPO/FUA flags are clear in the CDB_USAGE_DATA");
                if (usage_data_dpofua) {
                        logging(LOG_NORMAL, "[FAILED] DpoFua not clear "
                                "in CDB_USAGE_DATE");
                        CU_FAIL("DpoFua not clear in CDB_USAGE_DATE");
                }
        }

        scsi_free_scsi_task(rso_task);
}
void
test_modesense6_residuals(void)
{
        struct scsi_task *ms_task = NULL;

        logging(LOG_VERBOSE, LOG_BLANK_LINE);
        logging(LOG_VERBOSE, "Test of MODESENSE6 Residuals");

        logging(LOG_VERBOSE, "MODESENSE6 command should not result in any "
                "residuals");

        
        logging(LOG_VERBOSE, "Try a MODESENSE6 command with 4 bytes of "
                "transfer length and verify that we don't get residuals.");
        MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
                   SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 4,
                   EXPECT_STATUS_GOOD);

        logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched.");

        logging(LOG_VERBOSE, "Verify that we got at most 4 bytes of DATA-IN");
        if (ms_task->datain.size > 4) {
                logging(LOG_NORMAL, "[FAILED] got more than 4 bytes of "
                        "DATA-IN.");
        } else {
                logging(LOG_VERBOSE, "[SUCCESS] <= 4 bytes of DATA-IN "
                        "received.");
        }
        CU_ASSERT_TRUE(ms_task->datain.size <= 4);


        logging(LOG_VERBOSE, "Verify residual overflow flag not set");
        if (ms_task->residual_status == SCSI_RESIDUAL_OVERFLOW) {
                logging(LOG_VERBOSE, "[FAILED] Target set residual "
                        "overflow flag");
        }
        CU_ASSERT_NOT_EQUAL(ms_task->residual_status, SCSI_RESIDUAL_OVERFLOW);



        logging(LOG_VERBOSE, "Try a MODESENSE6 command with 255 bytes of "
                "transfer length and verify that we get residuals if the target returns less than the requested amount of data.");
        scsi_free_scsi_task(ms_task);
        MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
                   SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
                   EXPECT_STATUS_GOOD);
        logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched.");

        if (ms_task->datain.size == 255) {
                logging(LOG_VERBOSE, "We got all 255 bytes of data back "
                        "from the target. Verify that underflow is not set.");

                if (ms_task->residual_status == SCSI_RESIDUAL_UNDERFLOW) {
                        logging(LOG_VERBOSE, "[FAILED] Target set residual "
                                "underflow flag");
                } else {
                        logging(LOG_VERBOSE, "[SUCCESS] Residual underflow "
                                "is not set");
                }
                CU_ASSERT_NOT_EQUAL(ms_task->residual_status,
                                SCSI_RESIDUAL_UNDERFLOW);
        } else {
                logging(LOG_VERBOSE, "We got less than the requested 255 bytes "
                        "from the target. Verify that underflow is set.");

                if (ms_task->residual_status != SCSI_RESIDUAL_UNDERFLOW) {
                        logging(LOG_VERBOSE, "[FAILED] Target did not set "
                                "residual underflow flag");
                } else {
                        logging(LOG_VERBOSE, "[SUCCESS] Residual underflow "
                                "is set");
                }
                CU_ASSERT_EQUAL(ms_task->residual_status,
                                SCSI_RESIDUAL_UNDERFLOW);
        }

        scsi_free_scsi_task(ms_task);
}
示例#3
0
void
test_verify16_dpo(void)
{ 
        int dpofua, usage_data_dpo;
        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 VERIFY16 DPO flag");

        CHECK_FOR_SBC;

        READ10(sd, NULL, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
               EXPECT_STATUS_GOOD);

        logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
        MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
                   SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
                   EXPECT_STATUS_GOOD);

        logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
        ms = scsi_datain_unmarshall(ms_task);
        dpofua = ms && (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) {
                VERIFY16(sd, 0, block_size, block_size, 0, 1, 0, scratch,
                         EXPECT_STATUS_GOOD);
        } else {
                VERIFY16(sd, 0, block_size, block_size, 0, 1, 0, scratch,
                         EXPECT_INVALID_FIELD_IN_CDB);
        }

        logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
                "for VERIFY16");
        REPORT_SUPPORTED_OPCODES(sd, &rso_task,
                                 0, SCSI_REPORT_SUPPORTING_OPCODE,
                                 SCSI_OPCODE_VERIFY16,
                                 0,
                                 65535,
                                 EXPECT_STATUS_GOOD);
        logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
        rsoc = scsi_datain_unmarshall(rso_task);
        CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc);

        usage_data_dpo = rsoc ? rsoc->cdb_usage_data[1] & 0x10 : -1;
        if (dpofua) {
                logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO flag "
                        "is set in the CDB_USAGE_DATA");
                CU_ASSERT_EQUAL(usage_data_dpo, 0x10);
        } else {
                logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO "
                        "flag is clear in the CDB_USAGE_DATA");
                CU_ASSERT_EQUAL(usage_data_dpo, 0x00);
        }

        scsi_free_scsi_task(rso_task);
}