| 17 | using namespace scsi_defs; |
| 18 | |
| 19 | string scsi_command_util::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uint8_t> buf, int length, int sector_size) |
| 20 | { |
| 21 | assert(cmd == scsi_command::eCmdModeSelect6 || cmd == scsi_command::eCmdModeSelect10); |
| 22 | assert(length >= 0); |
| 23 | |
| 24 | string result; |
| 25 | |
| 26 | // PF |
| 27 | if (!(cdb[1] & 0x10)) { |
| 28 | // Vendor-specific parameters (SCSI-1) are not supported. |
| 29 | // Do not report an error in order to support Apple's HD SC Setup. |
| 30 | return result; |
| 31 | } |
| 32 | |
| 33 | // Skip block descriptors |
| 34 | int offset; |
| 35 | if (cmd == scsi_command::eCmdModeSelect10) { |
| 36 | offset = 8 + GetInt16(buf, 6); |
| 37 | } |
| 38 | else { |
| 39 | offset = 4 + buf[3]; |
| 40 | } |
| 41 | length -= offset; |
| 42 | |
| 43 | bool has_valid_page_code = false; |
| 44 | |
| 45 | // Parse the pages |
| 46 | while (length > 0) { |
| 47 | // Format device page |
| 48 | if (const int page = buf[offset]; page == 0x03) { |
| 49 | if (length < 14) { |
| 50 | throw scsi_exception(sense_key::illegal_request, asc::invalid_field_in_parameter_list); |
| 51 | } |
| 52 | |
| 53 | // With this page the sector size for a subsequent FORMAT can be selected, but only very few |
| 54 | // drives support this, e.g FUJITSU M2624S |
| 55 | // We are fine as long as the current sector size remains unchanged |
| 56 | if (GetInt16(buf, offset + 12) != sector_size) { |
| 57 | // With piscsi it is not possible to permanently (by formatting) change the sector size, |
| 58 | // because the size is an externally configurable setting only |
| 59 | spdlog::warn("In order to change the sector size use the -b option when launching piscsi"); |
| 60 | throw scsi_exception(sense_key::illegal_request, asc::invalid_field_in_parameter_list); |
| 61 | } |
| 62 | |
| 63 | has_valid_page_code = true; |
| 64 | } |
| 65 | else { |
| 66 | stringstream s; |
| 67 | s << "Unknown MODE SELECT page code: $" << setfill('0') << setw(2) << hex << page; |
| 68 | result = s.str(); |
| 69 | } |
| 70 | |
| 71 | // Advance to the next page |
| 72 | const int size = buf[offset + 1] + 2; |
| 73 | |
| 74 | length -= size; |
| 75 | offset += size; |
| 76 | } |
nothing calls this directly
no test coverage detected