Skip to content

Commit de4ccdb

Browse files
DPOFUA support: meta
1 parent f1781e3 commit de4ccdb

File tree

1 file changed

+10
-17
lines changed

1 file changed

+10
-17
lines changed

scsi.cpp

+10-17
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const std::map<scsi::scsi_opcode, scsi_opcode_details> scsi_a3_data {
4343
{ scsi::scsi_opcode::o_unmap, { { 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07 }, 10, "unmap" } },
4444
{ scsi::scsi_opcode::o_read_16, { { 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07 }, 16, "read 16" } },
4545
{ scsi::scsi_opcode::o_compare_and_write, { { 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x07 }, 16, "compare and write" } },
46-
{ scsi::scsi_opcode::o_write_16, { { 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07 }, 16, "write 16" } },
46+
{ scsi::scsi_opcode::o_write_16, { { 0x8a, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07 }, 16, "write 16" } },
4747
{ scsi::scsi_opcode::o_get_lba_status, { { 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07 }, 16, "get lba status" } },
4848
{ scsi::scsi_opcode::o_report_luns, { { 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07 }, 12, "report luns" } },
4949
{ scsi::scsi_opcode::o_rep_sup_oper, { { 0xff, 0x1f, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07 }, 12, "report supported operations" } },
@@ -103,6 +103,8 @@ scsi_response scsi::mode_sense_6(const std::string & identifier, const uint64_t
103103
response.io.what.data.second = 4;
104104
response.io.what.data.first = new uint8_t[response.io.what.data.second]();
105105
response.io.what.data.first[0] = response.io.what.data.second - 1; // length
106+
response.io.what.data.first[1] = 0; // medium type
107+
response.io.what.data.first[2] = 16; // DPOFUA
106108
}
107109

108110
return response;
@@ -232,6 +234,7 @@ scsi_response scsi::inquiry(const std::string & identifier, const uint64_t lun,
232234
response.io.what.data.first[3] = response.io.what.data.second - 4;
233235
response.io.what.data.first[4] = 0x1c; // device has an RPM of 7200 (fake!)
234236
response.io.what.data.first[5] = 0x20;
237+
response.io.what.data.first[8] = 0x02; // FUAB
235238
// ... set all to 'not set'
236239
}
237240
else if (CDB[2] == 0xb2) { // logical block provisioning vpd page
@@ -601,10 +604,13 @@ scsi_response scsi::report_supported_operation_codes(const std::string & identif
601604
auto it = scsi_a3_data.find(scsi::scsi_opcode(req_operation_code));
602605
if (it != scsi_a3_data.end()) {
603606
response.io.is_inline = true;
604-
response.io.what.data.second = 4 + it->second.data.size();
607+
auto cdb_size = it->second.data.size();
608+
response.io.what.data.second = 4 + cdb_size;
605609
response.io.what.data.first = new uint8_t[response.io.what.data.second]();
606-
response.io.what.data.first[1] = 3 + it->second.data.size();
607-
memcpy(response.io.what.data.first + 4, it->second.data.data(), it->second.data.size());
610+
response.io.what.data.first[1] = 0x03; // SUPPORT == 0b011
611+
response.io.what.data.first[2] = cdb_size >> 8;
612+
response.io.what.data.first[3] = cdb_size;
613+
memcpy(response.io.what.data.first + 4, it->second.data.data(), cdb_size);
608614

609615
ok = true;
610616
}
@@ -972,19 +978,6 @@ std::optional<std::vector<uint8_t> > scsi::validate_request(const uint64_t lba,
972978
}
973979
}
974980

975-
if (opcode == o_read_10 || opcode == o_read_16 || opcode == o_write_10 || opcode == o_write_16 ||
976-
opcode == o_write_verify_10 || opcode == o_compare_and_write) {
977-
if (CDB[1] & 16) { // DPO
978-
DOLOG(logging::ll_debug, "scsi::validate_request", "-", "DPO not supported");
979-
return error_invalid_field();
980-
}
981-
982-
if (CDB[1] & 8) { // FUA
983-
DOLOG(logging::ll_debug, "scsi::validate_request", "-", "FUA not supported");
984-
return error_invalid_field();
985-
}
986-
}
987-
988981
if ((opcode == o_write_same_10 || opcode == o_write_same_16) && (CDB[1] & 16) == 16 && (CDB[1] & 8) == 0) {
989982
DOLOG(logging::ll_debug, "scsi::validate_request", "-", "WRITE_SAME with ANCHOR=1 and UNMAP=0 is a failure");
990983
return error_invalid_field();

0 commit comments

Comments
 (0)