From 0e8d89e8277a762d1e84eeb67c234815ecca697d Mon Sep 17 00:00:00 2001 From: Uwe Seimet <48174652+uweseimet@users.noreply.github.com> Date: Sun, 27 Feb 2022 22:58:01 +0100 Subject: [PATCH] Code cleanup, in particular related to MODE SENSE (#699) * Replace member functions * Fixed TODO * Added TODOs * Added TODOs * Removed duplicate code * Fixed return value * CD-ROM mode pages are provided by the CD-ROM implementation * MO mode pages are provided by the MO implementation * Comment update * Removed duplicate code * Removed more duplicate code * Optimization * Updated mode page size handling * Addec TODO * Started more flexible mode page handling * Map mode pages * Page 0 must be last * Error handling update * Updated size handling * Updated map handling * Use map references * Move superclass call * Added comment * Host services also support mode page 0x3f (all pages) * Updated handling of page 0 * Removed duplicate code * Updated buffer size handling * Code cleanup * Removed duplicate code * Use calloc() * Removed duplicate code * Comment update * Fixed buffer offset * Fixed TODO * Added buffer size check * Comment udpate * Logging update * Updated logging * Avoid potential memory leak * Updated handling of page 0 * Added TODO * Comment update * Fixed error message * Use vector instead of byte array * Optimization * More optimizations * Removed duplicate code * Do not try to add more pages when buffer is full * Updated error message * Comment update, fixed host services message length handling * Code cleanup, optimizations * Updated payload handling for page 0 * Fixed TODO * Updated handling of PS field * Fixed offsets * Updated handling for page 0 * Code cleanup * More cleanup * Updated block descriptor handling * Result of REPORT LUNS must not depend on whether a device is ready or not * Printer uses a dynamically allocated buffer * Use realloc * Updated memory handling * Added assertion * Comment update * Fixed initialization * Reset byte transfer flag * Updated usage of realloc * Reverted some changes * Re-added buffer size check * Renaming * Inquiry for hard disk must also work when drive is not ready * Primary device checks EVPD * Added page code check to Inquiry * Explicitly set response level format * Added comment * Removed useless cast * Fixed inconsistencies in setting the additional length * Logging uodate * Updated logging * Made methods const * Moved code * Added TODO * Added vendor page * Reduced visibility * Code cleanup * Mark override * Removed duplicate cast * Synchronized host services mode page handling with other code * Added TODO * Signature update * Moved code * Removed duplicate code * Fixed TODO * Removed duplicate code * Added buffer size check * Improved buffer size check * Code cleanup * Removed useless assertions * Cleanup * Renaming * Added overrides * Removed unnecessary casts * Cleanup * Added TODO * Removed obsolete memset * Removed duplicate code * Logging update * Logging update * Assertion update * Removed useless comments * Code cleanup * Removed obsolete casts * User super typedef * Updated log messages * Fixed #712 * Updated error handling * Removed useless assertions * Reduced casts to Disk* * Updated sector size list argument * Removed obsolete casts * Removed comment --- src/raspberrypi/controllers/sasidev_ctrl.cpp | 28 +- src/raspberrypi/controllers/sasidev_ctrl.h | 7 +- src/raspberrypi/controllers/scsidev_ctrl.cpp | 33 +- src/raspberrypi/devices/device.h | 4 - src/raspberrypi/devices/device_factory.cpp | 20 +- src/raspberrypi/devices/disk.cpp | 452 +++++-------------- src/raspberrypi/devices/disk.h | 25 +- src/raspberrypi/devices/host_services.cpp | 107 ++--- src/raspberrypi/devices/host_services.h | 6 +- src/raspberrypi/devices/mode_page_device.cpp | 95 +++- src/raspberrypi/devices/mode_page_device.h | 15 +- src/raspberrypi/devices/primary_device.cpp | 37 +- src/raspberrypi/devices/primary_device.h | 1 + src/raspberrypi/devices/sasihd.cpp | 41 +- src/raspberrypi/devices/sasihd.h | 4 +- src/raspberrypi/devices/scsi_daynaport.cpp | 8 + src/raspberrypi/devices/scsi_daynaport.h | 1 + src/raspberrypi/devices/scsi_host_bridge.cpp | 197 +------- src/raspberrypi/devices/scsi_printer.cpp | 7 +- src/raspberrypi/devices/scsicd.cpp | 52 ++- src/raspberrypi/devices/scsicd.h | 9 +- src/raspberrypi/devices/scsihd.cpp | 36 +- src/raspberrypi/devices/scsihd.h | 7 +- src/raspberrypi/devices/scsihd_nec.cpp | 43 +- src/raspberrypi/devices/scsihd_nec.h | 10 +- src/raspberrypi/devices/scsimo.cpp | 86 ++-- src/raspberrypi/devices/scsimo.h | 14 +- src/raspberrypi/gpiobus.h | 50 +- src/raspberrypi/rascsi.cpp | 4 +- src/raspberrypi/scsi.h | 1 + 30 files changed, 525 insertions(+), 875 deletions(-) diff --git a/src/raspberrypi/controllers/sasidev_ctrl.cpp b/src/raspberrypi/controllers/sasidev_ctrl.cpp index 5fa72f51..b02e6a6f 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.cpp +++ b/src/raspberrypi/controllers/sasidev_ctrl.cpp @@ -115,7 +115,7 @@ void SASIDEV::Connect(int id, BUS *bus) // Set the logical unit // //--------------------------------------------------------------------------- -void SASIDEV::SetUnit(int no, Device *dev) +void SASIDEV::SetUnit(int no, PrimaryDevice *dev) { ASSERT(no < UnitMax); @@ -626,7 +626,7 @@ void SASIDEV::DataOut() void SASIDEV::Error(ERROR_CODES::sense_key sense_key, ERROR_CODES::asc asc, ERROR_CODES::status status) { // Get bus information - ((GPIOBUS*)ctrl.bus)->Aquire(); + ctrl.bus->Aquire(); // Reset check if (ctrl.bus->GetRST()) { @@ -664,7 +664,7 @@ void SASIDEV::CmdTestUnitReady() LOGTRACE("%s TEST UNIT READY Command ", __PRETTY_FUNCTION__); // Command processing on drive - ((Disk *)ctrl.device)->TestUnitReady(this); + ctrl.device->TestUnitReady(this); } //--------------------------------------------------------------------------- @@ -690,7 +690,7 @@ void SASIDEV::CmdRequestSense() LOGTRACE( "%s REQUEST SENSE Command ", __PRETTY_FUNCTION__); // Command processing on drive - ((Disk *)ctrl.device)->RequestSense(this); + ctrl.device->RequestSense(this); } //--------------------------------------------------------------------------- @@ -847,8 +847,8 @@ void SASIDEV::CmdAssign() { LOGTRACE("%s ASSIGN Command ", __PRETTY_FUNCTION__); - // Command processing on drive - bool status = ((Disk *)ctrl.device)->CheckReady(); + // Command processing on device + bool status = ctrl.device->CheckReady(); if (!status) { // Failure (Error) Error(); @@ -871,8 +871,8 @@ void SASIDEV::CmdSpecify() { LOGTRACE("%s SPECIFY Command ", __PRETTY_FUNCTION__); - // Command processing on drive - bool status = ((Disk *)ctrl.device)->CheckReady(); + // Command processing on device + bool status =ctrl.device->CheckReady(); if (!status) { // Failure (Error) Error(); @@ -1143,10 +1143,12 @@ bool SASIDEV::XferOut(bool cont) case SASIDEV::eCmdWrite16: case SASIDEV::eCmdVerify10: case SASIDEV::eCmdVerify16: + { // If we're a host bridge, use the host bridge's SendMessage10 function // TODO This class must not know about SCSIBR - if (device->IsBridge()) { - if (!((SCSIBR*)device)->SendMessage10(ctrl.cmd, ctrl.buffer)) { + SCSIBR *bridge = dynamic_cast(device); + if (bridge) { + if (!bridge->SendMessage10(ctrl.cmd, ctrl.buffer)) { // write failed return false; } @@ -1158,8 +1160,9 @@ bool SASIDEV::XferOut(bool cont) // Special case Write function for DaynaPort // TODO This class must not know about DaynaPort - if (device->IsDaynaPort()) { - if (!((SCSIDaynaPort*)device)->Write(ctrl.cmd, ctrl.buffer, ctrl.length)) { + SCSIDaynaPort *daynaport = dynamic_cast(device); + if (daynaport) { + if (!daynaport->Write(ctrl.cmd, ctrl.buffer, ctrl.length)) { // write failed return false; } @@ -1191,6 +1194,7 @@ bool SASIDEV::XferOut(bool cont) // If normal, work setting ctrl.offset = 0; break; + } // SPECIFY(SASI only) case SASIDEV::eCmdInvalid: diff --git a/src/raspberrypi/controllers/sasidev_ctrl.h b/src/raspberrypi/controllers/sasidev_ctrl.h index 136dc14f..c4253c1e 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.h +++ b/src/raspberrypi/controllers/sasidev_ctrl.h @@ -21,6 +21,7 @@ #include "fileio.h" class Device; +class PrimaryDevice; //=========================================================================== // @@ -123,10 +124,10 @@ public: DWORD length; // Transfer remaining length // Logical unit - Device *unit[UnitMax]; + PrimaryDevice *unit[UnitMax]; // The current device - Device *device; + PrimaryDevice *device; // The LUN from the IDENTIFY message int lun; @@ -144,7 +145,7 @@ public: // Connect void Connect(int id, BUS *sbus); // Controller connection Device* GetUnit(int no); // Get logical unit - void SetUnit(int no, Device *dev); // Logical unit setting + void SetUnit(int no, PrimaryDevice *dev); // Logical unit setting bool HasUnit(); // Has a valid logical unit // Other diff --git a/src/raspberrypi/controllers/scsidev_ctrl.cpp b/src/raspberrypi/controllers/scsidev_ctrl.cpp index e8360532..c7efe4c9 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.cpp +++ b/src/raspberrypi/controllers/scsidev_ctrl.cpp @@ -27,6 +27,7 @@ SCSIDEV::SCSIDEV() : SASIDEV() { + scsi.is_byte_transfer = false; scsi.bytes_to_transfer = 0; shutdown_mode = NONE; @@ -45,6 +46,7 @@ SCSIDEV::~SCSIDEV() void SCSIDEV::Reset() { + scsi.is_byte_transfer = false; scsi.bytes_to_transfer = 0; // Work initialization @@ -63,7 +65,7 @@ BUS::phase_t SCSIDEV::Process(int initiator_id) } // Get bus information - ((GPIOBUS*)ctrl.bus)->Aquire(); + ctrl.bus->Aquire(); // Check to see if the reset signal was asserted if (ctrl.bus->GetRST()) { @@ -356,7 +358,7 @@ void SCSIDEV::MsgOut() void SCSIDEV::Error(ERROR_CODES::sense_key sense_key, ERROR_CODES::asc asc, ERROR_CODES::status status) { // Get bus information - ((GPIOBUS*)ctrl.bus)->Aquire(); + ctrl.bus->Aquire(); // Reset check if (ctrl.bus->GetRST()) { @@ -402,24 +404,11 @@ void SCSIDEV::Send() ASSERT(!ctrl.bus->GetREQ()); ASSERT(ctrl.bus->GetIO()); - //if Length! = 0, send if (ctrl.length != 0) { LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Sending handhake with offset " + to_string(ctrl.offset) + ", length " + to_string(ctrl.length)).c_str()); - // TODO Get rid of Daynaport specific code in this class - // The Daynaport needs to have a delay after the size/flags field - // of the read response. In the MacOS driver, it looks like the - // driver is doing two "READ" system calls. - int len; - if (ctrl.unit[0] && ctrl.unit[0]->IsDaynaPort()) { - len = ((GPIOBUS*)ctrl.bus)->SendHandShake( - &ctrl.buffer[ctrl.offset], ctrl.length, SCSIDaynaPort::DAYNAPORT_READ_HEADER_SZ); - } - else - { - len = ctrl.bus->SendHandShake(&ctrl.buffer[ctrl.offset], ctrl.length, BUS::SEND_NO_DELAY); - } + int len = ctrl.bus->SendHandShake(&ctrl.buffer[ctrl.offset], ctrl.length, ctrl.unit[0]->GetSendDelay()); // If you cannot send all, move to status phase if (len != (int)ctrl.length) { @@ -522,13 +511,13 @@ void SCSIDEV::Receive() // Length != 0 if received if (ctrl.length != 0) { - LOGTRACE("%s length is %d", __PRETTY_FUNCTION__, (int)ctrl.length); + LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, (int)ctrl.length); // Receive len = ctrl.bus->ReceiveHandShake(&ctrl.buffer[ctrl.offset], ctrl.length); // If not able to receive all, move to status phase if (len != (int)ctrl.length) { - LOGERROR("%s Not able to receive %d data, only received %d. Going to error",__PRETTY_FUNCTION__, (int)ctrl.length, len); + LOGERROR("%s Not able to receive %d bytes of data, only received %d. Going to error",__PRETTY_FUNCTION__, (int)ctrl.length, len); Error(); return; } @@ -658,7 +647,7 @@ void SCSIDEV::Receive() // Transfer period factor (limited to 50 x 4 = 200ns) scsi.syncperiod = scsi.msb[i + 3]; if (scsi.syncperiod > 50) { - scsi.syncoffset = 50; + scsi.syncperiod = 50; } // REQ/ACK offset(limited to 16) @@ -736,13 +725,13 @@ void SCSIDEV::ReceiveBytes() ASSERT(!ctrl.bus->GetIO()); if (ctrl.length) { - LOGTRACE("%s length is %d", __PRETTY_FUNCTION__, ctrl.length); + LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, ctrl.length); len = ctrl.bus->ReceiveHandShake(&ctrl.buffer[ctrl.offset], ctrl.length); // If not able to receive all, move to status phase if (len != ctrl.length) { - LOGERROR("%s Not able to receive %d data, only received %d. Going to error", + LOGERROR("%s Not able to receive %d bytes of data, only received %d. Going to error", __PRETTY_FUNCTION__, ctrl.length, len); Error(); return; @@ -904,6 +893,8 @@ bool SCSIDEV::XferOut(bool cont) ASSERT(ctrl.phase == BUS::dataout); + scsi.is_byte_transfer = false; + PrimaryDevice *device = dynamic_cast(ctrl.unit[GetEffectiveLun()]); if (device && ctrl.cmd[0] == scsi_defs::eCmdWrite6) { return device->WriteBytes(ctrl.buffer, scsi.bytes_to_transfer); diff --git a/src/raspberrypi/devices/device.h b/src/raspberrypi/devices/device.h index aeb94d9d..b3b321f8 100644 --- a/src/raspberrypi/devices/device.h +++ b/src/raspberrypi/devices/device.h @@ -184,8 +184,4 @@ public: bool IsSASIHD() const { return type == "SAHD"; } bool IsSCSIHD() const { return type == "SCHD" || type == "SCRM"; } - bool IsCdRom() const { return type == "SCCD"; } - bool IsMo() const { return type == "SCMO"; } - bool IsBridge() const { return type == "SCBR"; } - bool IsDaynaPort() const { return type == "SCDP"; } }; diff --git a/src/raspberrypi/devices/device_factory.cpp b/src/raspberrypi/devices/device_factory.cpp index 86da4c23..989cf7f1 100644 --- a/src/raspberrypi/devices/device_factory.cpp +++ b/src/raspberrypi/devices/device_factory.cpp @@ -31,7 +31,6 @@ DeviceFactory::DeviceFactory() sector_sizes[SCHD] = { 512, 1024, 2048, 4096 }; sector_sizes[SCRM] = { 512, 1024, 2048, 4096 }; sector_sizes[SCMO] = { 512, 1024, 2048, 4096 }; - // Some old Sun CD-ROM drives support 512 bytes per sector sector_sizes[SCCD] = { 512, 2048}; // 128 MB, 512 bytes per sector, 248826 sectors @@ -124,20 +123,17 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename) try { switch (type) { case SAHD: - device = new SASIHD(); + device = new SASIHD(sector_sizes[SAHD]); device->SetSupportedLuns(2); device->SetProduct("SASI HD"); - ((Disk *)device)->SetSectorSizes(sector_sizes[SAHD]); break; case SCHD: { string ext = GetExtension(filename); if (ext == "hdn" || ext == "hdi" || ext == "nhd") { - device = new SCSIHD_NEC(); - ((Disk *)device)->SetSectorSizes({ 512 }); + device = new SCSIHD_NEC({ 512 }); } else { - device = new SCSIHD(false); - ((Disk *)device)->SetSectorSizes(sector_sizes[SCHD]); + device = new SCSIHD(sector_sizes[SCHD], false); // Some Apple tools require a particular drive identification if (ext == "hda") { @@ -151,34 +147,30 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename) } case SCRM: - device = new SCSIHD(true); + device = new SCSIHD(sector_sizes[SCRM], true); device->SetProtectable(true); device->SetStoppable(true); device->SetRemovable(true); device->SetLockable(true); device->SetProduct("SCSI HD (REM.)"); - ((Disk *)device)->SetSectorSizes(sector_sizes[SCRM]); break; case SCMO: - device = new SCSIMO(); + device = new SCSIMO(sector_sizes[SCMO], geometries[SCMO]); device->SetProtectable(true); device->SetStoppable(true); device->SetRemovable(true); device->SetLockable(true); device->SetProduct("SCSI MO"); - ((Disk *)device)->SetSectorSizes(sector_sizes[SCRM]); - ((Disk *)device)->SetGeometries(geometries[SCMO]); break; case SCCD: - device = new SCSICD(); + device = new SCSICD(sector_sizes[SCCD]); device->SetReadOnly(true); device->SetStoppable(true); device->SetRemovable(true); device->SetLockable(true); device->SetProduct("SCSI CD-ROM"); - ((Disk *)device)->SetSectorSizes(sector_sizes[SCCD]); break; case SCBR: diff --git a/src/raspberrypi/devices/disk.cpp b/src/raspberrypi/devices/disk.cpp index b4170a92..02af040c 100644 --- a/src/raspberrypi/devices/disk.cpp +++ b/src/raspberrypi/devices/disk.cpp @@ -38,8 +38,8 @@ Disk::Disk(const string& id) : ModePageDevice(id), ScsiBlockCommands() dispatcher.AddCommand(eCmdRead6, "Read6", &Disk::Read6); dispatcher.AddCommand(eCmdWrite6, "Write6", &Disk::Write6); dispatcher.AddCommand(eCmdSeek6, "Seek6", &Disk::Seek6); - dispatcher.AddCommand(eCmdReserve6, "Reserve6", &Disk::Reserve6); - dispatcher.AddCommand(eCmdRelease6, "Release6", &Disk::Release6); + dispatcher.AddCommand(eCmdReserve6, "Reserve6", &Disk::Reserve); + dispatcher.AddCommand(eCmdRelease6, "Release6", &Disk::Release); dispatcher.AddCommand(eCmdStartStop, "StartStopUnit", &Disk::StartStopUnit); dispatcher.AddCommand(eCmdSendDiag, "SendDiagnostic", &Disk::SendDiagnostic); dispatcher.AddCommand(eCmdRemoval, "PreventAllowMediumRemoval", &Disk::PreventAllowMediumRemoval); @@ -54,8 +54,8 @@ Disk::Disk(const string& id) : ModePageDevice(id), ScsiBlockCommands() dispatcher.AddCommand(eCmdSynchronizeCache10, "SynchronizeCache10", &Disk::SynchronizeCache10); dispatcher.AddCommand(eCmdSynchronizeCache16, "SynchronizeCache16", &Disk::SynchronizeCache16); dispatcher.AddCommand(eCmdReadDefectData10, "ReadDefectData10", &Disk::ReadDefectData10); - dispatcher.AddCommand(eCmdReserve10, "Reserve10", &Disk::Reserve10); - dispatcher.AddCommand(eCmdRelease10, "Release10", &Disk::Release10); + dispatcher.AddCommand(eCmdReserve10, "Reserve10", &Disk::Reserve); + dispatcher.AddCommand(eCmdRelease10, "Release10", &Disk::Release); dispatcher.AddCommand(eCmdRead16, "Read16", &Disk::Read16); dispatcher.AddCommand(eCmdWrite16, "Write16", &Disk::Write16); dispatcher.AddCommand(eCmdVerify16, "Verify16", &Disk::Verify16); @@ -101,7 +101,7 @@ bool Disk::Dispatch(SCSIDEV *controller) //--------------------------------------------------------------------------- void Disk::Open(const Filepath& path) { - ASSERT(disk.blocks > 0); + assert(disk.blocks > 0); SetReady(true); @@ -183,8 +183,6 @@ void Disk::Read6(SASIDEV *controller) { uint64_t start; if (GetStartAndCount(controller, start, ctrl->blocks, RW6)) { - LOGDEBUG("%s READ(6) command record=$%08X blocks=%d", __PRETTY_FUNCTION__, (uint32_t)start, ctrl->blocks); - Read(controller, start); } } @@ -193,8 +191,6 @@ void Disk::Read10(SASIDEV *controller) { uint64_t start; if (GetStartAndCount(controller, start, ctrl->blocks, RW10)) { - LOGDEBUG("%s READ(10) command record=$%08X blocks=%d", __PRETTY_FUNCTION__, (uint32_t)start, ctrl->blocks); - Read(controller, start); } } @@ -203,8 +199,6 @@ void Disk::Read16(SASIDEV *controller) { uint64_t start; if (GetStartAndCount(controller, start, ctrl->blocks, RW16)) { - LOGDEBUG("%s READ(16) command record=$%08X blocks=%d", __PRETTY_FUNCTION__, (uint32_t)start, ctrl->blocks); - Read(controller, start); } } @@ -267,8 +261,6 @@ void Disk::Write6(SASIDEV *controller) { uint64_t start; if (GetStartAndCount(controller, start, ctrl->blocks, RW6)) { - LOGDEBUG("%s WRITE(6) command record=$%08X blocks=%d", __PRETTY_FUNCTION__, (uint32_t)start, ctrl->blocks); - Write(controller, start); } } @@ -277,8 +269,6 @@ void Disk::Write10(SASIDEV *controller) { uint64_t start; if (GetStartAndCount(controller, start, ctrl->blocks, RW10)) { - LOGDEBUG("%s WRITE(10) command record=$%08X blocks=%d",__PRETTY_FUNCTION__, (uint32_t)start, ctrl->blocks); - Write(controller, start); } } @@ -287,8 +277,6 @@ void Disk::Write16(SASIDEV *controller) { uint64_t start; if (GetStartAndCount(controller, start, ctrl->blocks, RW16)) { - LOGDEBUG("%s WRITE(16) command record=$%08X blocks=%d",__PRETTY_FUNCTION__, (uint32_t)start, ctrl->blocks); - Write(controller, start); } } @@ -329,8 +317,6 @@ void Disk::Verify10(SASIDEV *controller) // Get record number and block number uint64_t record; if (GetStartAndCount(controller, record, ctrl->blocks, RW10)) { - LOGDEBUG("%s VERIFY(10) command record=$%08X blocks=%d",__PRETTY_FUNCTION__, (uint32_t)record, ctrl->blocks); - Verify(controller, record); } } @@ -340,8 +326,6 @@ void Disk::Verify16(SASIDEV *controller) // Get record number and block number uint64_t record; if (GetStartAndCount(controller, record, ctrl->blocks, RW16)) { - LOGDEBUG("%s VERIFY(16) command record=$%08X blocks=%d",__PRETTY_FUNCTION__, (uint32_t)record, ctrl->blocks); - Verify(controller, record); } } @@ -396,7 +380,7 @@ void Disk::SynchronizeCache16(SASIDEV *controller) void Disk::ReadDefectData10(SASIDEV *controller) { - ctrl->length = ReadDefectData10(ctrl->cmd, ctrl->buffer); + ctrl->length = ReadDefectData10(ctrl->cmd, ctrl->buffer, ctrl->bufsize); if (ctrl->length <= 4) { controller->Error(); return; @@ -438,29 +422,9 @@ int Disk::ModeSense6(const DWORD *cdb, BYTE *buf) int length = (int)cdb[4]; memset(buf, 0, length); - // Get changeable flag - bool change = (cdb[2] & 0xc0) == 0x40; - - // Get page code (0x00 is valid from the beginning) - int page = cdb[2] & 0x3f; - bool valid = page == 0x00; - - LOGTRACE("%s Requesting mode page $%02X", __PRETTY_FUNCTION__, page); - // Basic information int size = 4; - // MEDIUM TYPE - if (IsMo()) { - // Optical reversible or erasable - buf[1] = 0x03; - } - - // DEVICE SPECIFIC PARAMETER - if (IsProtected()) { - buf[2] = 0x80; - } - // Add block descriptor if DBD is 0 if ((cdb[1] & 0x08) == 0) { // Mode parameter header, block descriptor length @@ -486,70 +450,14 @@ int Disk::ModeSense6(const DWORD *cdb, BYTE *buf) size = 12; } - // Page code 1 (read-write error recovery) - if (page == 0x01 || page == 0x3f) { - size += AddErrorPage(change, &buf[size]); - valid = true; - } - - // Page code 3 (format device) - if (page == 0x03 || page == 0x3f) { - size += AddFormatPage(change, &buf[size]); - valid = true; - } - - // Page code 4 (drive parameter) - if (page == 0x04 || page == 0x3f) { - size += AddDrivePage(change, &buf[size]); - valid = true; - } - - // Page code 6 (optical) - if (IsMo()) { - if (page == 0x06 || page == 0x3f) { - size += AddOptionPage(change, &buf[size]); - valid = true; - } - } - - // Page code 8 (caching) - if (page == 0x08 || page == 0x3f) { - size += AddCachePage(change, &buf[size]); - valid = true; - } - - // Page code 13 (CD-ROM) - if (IsCdRom()) { - if (page == 0x0d || page == 0x3f) { - size += AddCDROMPage(change, &buf[size]); - valid = true; - } - } - - // Page code 14 (CD-DA) - if (IsCdRom()) { - if (page == 0x0e || page == 0x3f) { - size += AddCDDAPage(change, &buf[size]); - valid = true; - } - } - - // Page (vendor special) - int ret = AddVendorPage(page, change, &buf[size]); - if (ret > 0) { - size += ret; - valid = true; - } - - if (!valid) { - LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, page); - SetStatusCode(STATUS_INVALIDCDB); + int pages_size = super::AddModePages(cdb, &buf[size], length - size); + if (!pages_size) { return 0; } + size += pages_size; // Do not return more than ALLOCATION LENGTH bytes if (size > length) { - LOGTRACE("%s %d bytes available, %d bytes requested", __PRETTY_FUNCTION__, size, length); size = length; } @@ -559,40 +467,18 @@ int Disk::ModeSense6(const DWORD *cdb, BYTE *buf) return size; } -int Disk::ModeSense10(const DWORD *cdb, BYTE *buf) +int Disk::ModeSense10(const DWORD *cdb, BYTE *buf, int max_length) { // Get length, clear buffer - int length = cdb[7]; - length <<= 8; - length |= cdb[8]; - if (length > 0x800) { - length = 0x800; + int length = (cdb[7] << 8) | cdb[8]; + if (length > max_length) { + length = max_length; } memset(buf, 0, length); - // Get changeable flag - bool change = (cdb[2] & 0xc0) == 0x40; - - // Get page code (0x00 is valid from the beginning) - int page = cdb[2] & 0x3f; - bool valid = page == 0x00; - - LOGTRACE("%s Requesting mode page $%02X", __PRETTY_FUNCTION__, page); - // Basic Information int size = 8; - // MEDIUM TYPE - if (IsMo()) { - // Optical reversible or erasable - buf[2] = 0x03; - } - - // DEVICE SPECIFIC PARAMETER - if (IsProtected()) { - buf[3] = 0x80; - } - // Add block descriptor if DBD is 0 if ((cdb[1] & 0x08) == 0) { // Only if ready @@ -646,70 +532,14 @@ int Disk::ModeSense10(const DWORD *cdb, BYTE *buf) } } - // Page code 1 (read-write error recovery) - if (page == 0x01 || page == 0x3f) { - size += AddErrorPage(change, &buf[size]); - valid = true; - } - - // Page code 3 (format device) - if (page == 0x03 || page == 0x3f) { - size += AddFormatPage(change, &buf[size]); - valid = true; - } - - // Page code 4 (drive parameter) - if (page == 0x04 || page == 0x3f) { - size += AddDrivePage(change, &buf[size]); - valid = true; - } - - // Page code 6 (optical) - if (IsMo()) { - if (page == 0x06 || page == 0x3f) { - size += AddOptionPage(change, &buf[size]); - valid = true; - } - } - - // Page code 8 (caching) - if (page == 0x08 || page == 0x3f) { - size += AddCachePage(change, &buf[size]); - valid = true; - } - - // Page code 13 (CD-ROM) - if (IsCdRom()) { - if (page == 0x0d || page == 0x3f) { - size += AddCDROMPage(change, &buf[size]); - valid = true; - } - } - - // Page code 14 (CD-DA) - if (IsCdRom()) { - if (page == 0x0e || page == 0x3f) { - size += AddCDDAPage(change, &buf[size]); - valid = true; - } - } - - // Page (vendor special) - int ret = AddVendorPage(page, change, &buf[size]); - if (ret > 0) { - size += ret; - valid = true; - } - - if (!valid) { - LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, page); - SetStatusCode(STATUS_INVALIDCDB); + int pages_size = super::AddModePages(cdb, &buf[size], length - size); + if (!pages_size) { return 0; } + size += pages_size; // Do not return more than ALLOCATION LENGTH bytes if (size > length) { - LOGTRACE("%s %d bytes available, %d bytes requested", __PRETTY_FUNCTION__, size, length); size = length; } @@ -720,28 +550,65 @@ int Disk::ModeSense10(const DWORD *cdb, BYTE *buf) return size; } -int Disk::AddErrorPage(bool change, BYTE *buf) +void Disk::SetDeviceParameters(BYTE *buf) { - // Set the message length - buf[0] = 0x01; - buf[1] = 0x0a; - - // Retry count is 0, limit time uses internal default value - return 12; + // DEVICE SPECIFIC PARAMETER + if (IsProtected()) { + buf[3] = 0x80; + } } -int Disk::AddFormatPage(bool change, BYTE *buf) +void Disk::AddModePages(map>& pages, int page, bool changeable) const { - // Set the message length - buf[0] = 0x80 | 0x03; - buf[1] = 0x16; + // Page code 1 (read-write error recovery) + if (page == 0x01 || page == 0x3f) { + AddErrorPage(pages, changeable); + } + + // Page code 3 (format device) + if (page == 0x03 || page == 0x3f) { + AddFormatPage(pages, changeable); + } + + // Page code 4 (drive parameter) + if (page == 0x04 || page == 0x3f) { + AddDrivePage(pages, changeable); + } + + // Page code 8 (caching) + if (page == 0x08 || page == 0x3f) { + AddCachePage(pages, changeable); + } + + // Page (vendor special) + AddVendorPage(pages, page, changeable); +} + +void Disk::AddErrorPage(map>& pages, bool) const +{ + vector buf(12); + + // Retry count is 0, limit time uses internal default value + + pages[1] = buf; +} + +void Disk::AddFormatPage(map>& pages, bool changeable) const +{ + vector buf(24); + + // Page can be saved + buf[0] = 0x80; // Show the number of bytes in the physical sector as changeable // (though it cannot be changed in practice) - if (change) { + if (changeable) { buf[0xc] = 0xff; buf[0xd] = 0xff; - return 24; + + pages[3] = buf; + + return; } if (IsReady()) { @@ -763,18 +630,18 @@ int Disk::AddFormatPage(bool change, BYTE *buf) buf[20] = 0x20; } - return 24; + pages[3] = buf; } -int Disk::AddDrivePage(bool change, BYTE *buf) +void Disk::AddDrivePage(map>& pages, bool changeable) const { - // Set the message length - buf[0] = 0x04; - buf[1] = 0x16; + vector buf(24); // No changeable area - if (change) { - return 24; + if (changeable) { + pages[4] = buf; + + return; } if (IsReady()) { @@ -791,81 +658,30 @@ int Disk::AddDrivePage(bool change, BYTE *buf) buf[0x5] = 0x8; } - return 24; + pages[4] = buf; } -int Disk::AddOptionPage(bool change, BYTE *buf) +void Disk::AddCachePage(map>& pages, bool) const { - // Set the message length - buf[0] = 0x06; - buf[1] = 0x02; - - // Do not report update blocks - return 4; -} - -int Disk::AddCachePage(bool change, BYTE *buf) -{ - // Set the message length - buf[0] = 0x08; - buf[1] = 0x0a; + vector buf(12); // Only read cache is valid, no prefetch - return 12; + + pages[8] = buf; } -int Disk::AddCDROMPage(bool change, BYTE *buf) +void Disk::AddVendorPage(map>&, int, bool) const { - // Set the message length - buf[0] = 0x0d; - buf[1] = 0x06; - - // No changeable area - if (change) { - return 8; - } - - // 2 seconds for inactive timer - buf[3] = 0x05; - - // MSF multiples are 60 and 75 respectively - buf[5] = 60; - buf[7] = 75; - - return 8; + // Nothing to add by default } -int Disk::AddCDDAPage(bool change, BYTE *buf) +int Disk::ReadDefectData10(const DWORD *cdb, BYTE *buf, int max_length) { - // Set the message length - buf[0] = 0x0e; - buf[1] = 0x0e; - - // Audio waits for operation completion and allows - // PLAY across multiple tracks - return 16; -} - -int Disk::AddVendorPage(int /*page*/, bool /*change*/, BYTE *buf) -{ - ASSERT(buf); - - return 0; -} - -int Disk::ReadDefectData10(const DWORD *cdb, BYTE *buf) -{ - ASSERT(cdb); - ASSERT(buf); - // Get length, clear buffer - DWORD length = cdb[7]; - length <<= 8; - length |= cdb[8]; - if (length > 0x800) { - length = 0x800; + int length = (cdb[7] << 8) | cdb[8]; + if (length > max_length) { + length = max_length; } - ASSERT((length >= 0) && (length < 0x800)); memset(buf, 0, length); // P/G/FORMAT @@ -909,17 +725,10 @@ bool Disk::Format(const DWORD *cdb) return true; } -//--------------------------------------------------------------------------- -// -// READ -// -//--------------------------------------------------------------------------- // TODO Read more than one block in a single call. Currently blocked by the SASI code (missing early range check) // and the track-oriented cache. int Disk::Read(const DWORD *cdb, BYTE *buf, uint64_t block) { - ASSERT(buf); - LOGTRACE("%s", __PRETTY_FUNCTION__); if (!CheckReady()) { @@ -939,14 +748,9 @@ int Disk::Read(const DWORD *cdb, BYTE *buf, uint64_t block) } // Success - return (1 << disk.size); + return 1 << disk.size; } -//--------------------------------------------------------------------------- -// -// WRITE check -// -//--------------------------------------------------------------------------- int Disk::WriteCheck(DWORD block) { // Status check @@ -968,20 +772,13 @@ int Disk::WriteCheck(DWORD block) } // Success - return (1 << disk.size); + return 1 << disk.size; } -//--------------------------------------------------------------------------- -// -// WRITE -// -//--------------------------------------------------------------------------- // TODO Write more than one block in a single call. Currently blocked by the SASI code (missing early range check) // and the track-oriented cache. bool Disk::Write(const DWORD *cdb, const BYTE *buf, DWORD block) { - ASSERT(buf); - LOGTRACE("%s", __PRETTY_FUNCTION__); // Error if not ready @@ -1011,6 +808,7 @@ bool Disk::Write(const DWORD *cdb, const BYTE *buf, DWORD block) return true; } +// TODO For SCSI the specification mandates that the block address is verified void Disk::Seek(SASIDEV *controller) { if (!CheckReady()) { @@ -1089,23 +887,13 @@ bool Disk::SendDiag(const DWORD *cdb) void Disk::ReadCapacity10(SASIDEV *controller) { + if (!CheckReady() || disk.blocks <= 0) { + controller->Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::MEDIUM_NOT_PRESENT); + return; + } + BYTE *buf = ctrl->buffer; - memset(buf, 0, 8); - - if (!CheckReady()) { - controller->Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::MEDIUM_NOT_PRESENT); - return; - } - - if (disk.blocks <= 0) { - controller->Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::MEDIUM_NOT_PRESENT); - - LOGWARN("%s Capacity not available, medium may not be present", __PRETTY_FUNCTION__); - - return; - } - // Create end of logical block address (disk.blocks-1) uint32_t blocks = disk.blocks - 1; buf[0] = (BYTE)(blocks >> 24); @@ -1128,15 +916,13 @@ void Disk::ReadCapacity10(SASIDEV *controller) void Disk::ReadCapacity16(SASIDEV *controller) { - BYTE *buf = ctrl->buffer; - - memset(buf, 0, 14); - if (!CheckReady() || disk.blocks <= 0) { controller->Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::MEDIUM_NOT_PRESENT); return; } + BYTE *buf = ctrl->buffer; + // Create end of logical block address (disk.blocks-1) uint64_t blocks = disk.blocks - 1; buf[0] = (BYTE)(blocks >> 56); @@ -1155,6 +941,8 @@ void Disk::ReadCapacity16(SASIDEV *controller) buf[10] = (BYTE)(length >> 8); buf[11] = (BYTE)length; + buf[12] = 0; + // Logical blocks per physical block: not reported (1 or more) buf[13] = 0; @@ -1184,7 +972,7 @@ void Disk::ReadCapacity16_ReadLong16(SASIDEV *controller) //--------------------------------------------------------------------------- // -// RESERVE(6) +// RESERVE/RELEASE(6/10) // // The reserve/release commands are only used in multi-initiator // environments. RaSCSI doesn't support this use case. However, some old @@ -1192,52 +980,12 @@ void Disk::ReadCapacity16_ReadLong16(SASIDEV *controller) // just respond with an OK status. // //--------------------------------------------------------------------------- -void Disk::Reserve6(SASIDEV *controller) +void Disk::Reserve(SASIDEV *controller) { controller->Status(); } -//--------------------------------------------------------------------------- -// -// RESERVE(10) -// -// The reserve/release commands are only used in multi-initiator -// environments. RaSCSI doesn't support this use case. However, some old -// versions of Solaris will issue the reserve/release commands. We will -// just respond with an OK status. -// -//--------------------------------------------------------------------------- -void Disk::Reserve10(SASIDEV *controller) -{ - controller->Status(); -} - -//--------------------------------------------------------------------------- -// -// RELEASE(6) -// -// The reserve/release commands are only used in multi-initiator -// environments. RaSCSI doesn't support this use case. However, some old -// versions of Solaris will issue the reserve/release commands. We will -// just respond with an OK status. -// -//--------------------------------------------------------------------------- -void Disk::Release6(SASIDEV *controller) -{ - controller->Status(); -} - -//--------------------------------------------------------------------------- -// -// RELEASE(10) -// -// The reserve/release commands are only used in multi-initiator -// environments. RaSCSI doesn't support this use case. However, some old -// versions of Solaris will issue the reserve/release commands. We will -// just respond with an OK status. -// -//--------------------------------------------------------------------------- -void Disk::Release10(SASIDEV *controller) +void Disk::Release(SASIDEV *controller) { controller->Status(); } @@ -1330,6 +1078,8 @@ bool Disk::GetStartAndCount(SASIDEV *controller, uint64_t& start, uint32_t& coun } } + LOGDEBUG("%s READ/WRITE/VERIFY command record=$%08X blocks=%d", __PRETTY_FUNCTION__, (uint32_t)start, count); + // Check capacity uint64_t capacity = GetBlockCount(); if (start > capacity || start + count > capacity) { diff --git a/src/raspberrypi/devices/disk.h b/src/raspberrypi/devices/disk.h index 44e4f95e..ffe92cee 100644 --- a/src/raspberrypi/devices/disk.h +++ b/src/raspberrypi/devices/disk.h @@ -96,10 +96,8 @@ private: void Seek10(SASIDEV *); void ReadCapacity10(SASIDEV *) override; void ReadCapacity16(SASIDEV *) override; - void Reserve6(SASIDEV *); - void Reserve10(SASIDEV *); - void Release6(SASIDEV *); - void Release10(SASIDEV *); + void Reserve(SASIDEV *); + void Release(SASIDEV *); public: @@ -117,7 +115,7 @@ public: bool SendDiag(const DWORD *cdb); // SEND DIAGNOSTIC command virtual int Read(const DWORD *cdb, BYTE *buf, uint64_t block); - int ReadDefectData10(const DWORD *cdb, BYTE *buf); + int ReadDefectData10(const DWORD *, BYTE *, int); uint32_t GetSectorSizeInBytes() const; void SetSectorSizeInBytes(uint32_t, bool); @@ -138,15 +136,14 @@ public: protected: int ModeSense6(const DWORD *cdb, BYTE *buf); - int ModeSense10(const DWORD *cdb, BYTE *buf); - virtual int AddErrorPage(bool change, BYTE *buf); - virtual int AddFormatPage(bool change, BYTE *buf); - virtual int AddDrivePage(bool change, BYTE *buf); - virtual int AddVendorPage(int page, bool change, BYTE *buf); - int AddOptionPage(bool change, BYTE *buf); - int AddCachePage(bool change, BYTE *buf); - int AddCDROMPage(bool change, BYTE *buf); - int AddCDDAPage(bool, BYTE *buf); + int ModeSense10(const DWORD *cdb, BYTE *buf, int); + virtual void SetDeviceParameters(BYTE *); + void AddModePages(map>&, int, bool) const override; + virtual void AddErrorPage(map>&, bool) const; + virtual void AddFormatPage(map>&, bool) const; + virtual void AddDrivePage(map>&, bool) const; + void AddCachePage(map>&, bool) const; + virtual void AddVendorPage(map>&, int, bool) const; // Internal disk data disk_t disk; diff --git a/src/raspberrypi/devices/host_services.cpp b/src/raspberrypi/devices/host_services.cpp index c2272e8c..0c25bdf0 100644 --- a/src/raspberrypi/devices/host_services.cpp +++ b/src/raspberrypi/devices/host_services.cpp @@ -101,107 +101,92 @@ void HostServices::StartStopUnit(SCSIDEV *controller) int HostServices::ModeSense6(const DWORD *cdb, BYTE *buf) { - // Get length, clear buffer + // Block descriptors cannot be returned + if (!(cdb[1] & 0x08)) { + return 0; + } + int length = (int)cdb[4]; memset(buf, 0, length); - // Get page code (0x00 is valid from the beginning) - int page = cdb[2] & 0x3f; - bool valid = page == 0x00; - - LOGTRACE("%s Requesting mode page $%02X", __PRETTY_FUNCTION__, page); - // Basic information int size = 4; - int ret = AddRealtimeClockPage(page, &buf[size]); - if (ret > 0) { - size += ret; - valid = true; - } - - if (!valid) { - LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, page); - SetStatusCode(STATUS_INVALIDCDB); + int pages_size = super::AddModePages(cdb, &buf[size], length - size); + if (!pages_size) { return 0; } + size += pages_size; // Do not return more than ALLOCATION LENGTH bytes if (size > length) { - LOGTRACE("%s %d bytes available, %d bytes requested", __PRETTY_FUNCTION__, size, length); size = length; } - // Final setting of mode data length buf[0] = size; return size; } -int HostServices::ModeSense10(const DWORD *cdb, BYTE *buf) +int HostServices::ModeSense10(const DWORD *cdb, BYTE *buf, int max_length) { - // Get length, clear buffer - int length = cdb[7]; - length <<= 8; - length |= cdb[8]; - if (length > 0x800) { - length = 0x800; - } - memset(buf, 0, length); - - // Get page code (0x00 is valid from the beginning) - int page = cdb[2] & 0x3f; - bool valid = page == 0x00; - - LOGTRACE("%s Requesting mode page $%02X", __PRETTY_FUNCTION__, page); - - // Basic Information - int size = 8; - - int ret = AddRealtimeClockPage(page, &buf[size]); - if (ret > 0) { - size += ret; - valid = true; - } - - if (!valid) { - LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, page); - SetStatusCode(STATUS_INVALIDCDB); + // Block descriptors cannot be returned + if (!(cdb[1] & 0x08)) { return 0; } + int length = (cdb[7] << 8) | cdb[8]; + if (length > max_length) { + length = max_length; + } + memset(buf, 0, length); + + // Basic information + int size = 8; + + int pages_size = super::AddModePages(cdb, &buf[size], length - size); + if (!pages_size) { + return 0; + } + size += pages_size; + // Do not return more than ALLOCATION LENGTH bytes if (size > length) { - LOGTRACE("%s %d bytes available, %d bytes requested", __PRETTY_FUNCTION__, size, length); size = length; } - // Final setting of mode data length buf[0] = size >> 8; buf[1] = size; return size; } -int HostServices::AddRealtimeClockPage(int page, BYTE *buf) +void HostServices::AddModePages(map>& pages, int page, bool changeable) const { - if (page == 0x20) { + if (page == 0x20 || page == 0x3f) { + AddRealtimeClockPage(pages, changeable); + } +} + +void HostServices::AddRealtimeClockPage(map>& pages, bool changeable) const +{ + vector buf(10); + + if (!changeable) { // Data structure version 1.0 - buf[0] = 0x01; - buf[1] = 0x00; + buf[2] = 0x01; + buf[3] = 0x00; std::time_t t = std::time(NULL); std::tm tm = *std::localtime(&t); - buf[2] = tm.tm_year; - buf[3] = tm.tm_mon; - buf[4] = tm.tm_mday; - buf[5] = tm.tm_hour; - buf[6] = tm.tm_min; + buf[4] = tm.tm_year; + buf[5] = tm.tm_mon; + buf[6] = tm.tm_mday; + buf[7] = tm.tm_hour; + buf[8] = tm.tm_min; // Ignore leap second for simplicity - buf[7] = tm.tm_sec < 60 ? tm.tm_sec : 59; - - return 8; + buf[9] = tm.tm_sec < 60 ? tm.tm_sec : 59; } - return 0; + pages[32] = buf; } diff --git a/src/raspberrypi/devices/host_services.h b/src/raspberrypi/devices/host_services.h index 23276189..d71ee9b2 100644 --- a/src/raspberrypi/devices/host_services.h +++ b/src/raspberrypi/devices/host_services.h @@ -11,6 +11,7 @@ #pragma once #include "mode_page_device.h" +#include using namespace std; @@ -29,7 +30,7 @@ public: void StartStopUnit(SCSIDEV *); int ModeSense6(const DWORD *, BYTE *); - int ModeSense10(const DWORD *, BYTE *); + int ModeSense10(const DWORD *, BYTE *, int); private: @@ -37,5 +38,6 @@ private: Dispatcher dispatcher; - int AddRealtimeClockPage(int, BYTE *); + void AddModePages(map>&, int, bool) const override; + void AddRealtimeClockPage(map>&, bool) const; }; diff --git a/src/raspberrypi/devices/mode_page_device.cpp b/src/raspberrypi/devices/mode_page_device.cpp index 7ebce681..d625d580 100644 --- a/src/raspberrypi/devices/mode_page_device.cpp +++ b/src/raspberrypi/devices/mode_page_device.cpp @@ -30,6 +30,66 @@ bool ModePageDevice::Dispatch(SCSIDEV *controller) return dispatcher.Dispatch(this, controller) ? true : super::Dispatch(controller); } +int ModePageDevice::AddModePages(const DWORD *cdb, BYTE *buf, int max_length) +{ + bool changeable = (cdb[2] & 0xc0) == 0x40; + + // Get page code (0x3f means all pages) + int page = cdb[2] & 0x3f; + + LOGTRACE("%s Requesting mode page $%02X", __PRETTY_FUNCTION__, page); + + // Mode page data mapped to the respective page numbers, C++ maps are ordered by key + map> pages; + AddModePages(pages, page, changeable); + + // If no mode data were added at all something must be wrong + if (pages.empty()) { + LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, page); + SetStatusCode(STATUS_INVALIDCDB); + return 0; + } + + int size = 0; + + vector page0; + for (auto const& page : pages) { + if (size + (int)page.second.size() > max_length) { + LOGWARN("Mode page data size exceeds reserved buffer size"); + + page0.clear(); + + break; + } + else { + // The specification mandates that page 0 must be returned after all others + if (page.first) { + // Page data + memcpy(&buf[size], page.second.data(), page.second.size()); + // Page code, PS bit may already have been set + buf[size] |= page.first; + // Page payload size + buf[size + 1] = page.second.size() - 2; + + size += page.second.size(); + } + else { + page0 = page.second; + } + } + } + + // Page 0 must be last + if (!page0.empty()) { + memcpy(&buf[size], page0.data(), page0.size()); + // Page payload size + buf[size + 1] = page0.size() - 2; + size += page0.size(); + } + + return size; +} + void ModePageDevice::ModeSense6(SASIDEV *controller) { ctrl->length = ModeSense6(ctrl->cmd, ctrl->buffer); @@ -43,7 +103,7 @@ void ModePageDevice::ModeSense6(SASIDEV *controller) void ModePageDevice::ModeSense10(SASIDEV *controller) { - ctrl->length = ModeSense10(ctrl->cmd, ctrl->buffer); + ctrl->length = ModeSense10(ctrl->cmd, ctrl->buffer, ctrl->bufsize); if (ctrl->length <= 0) { controller->Error(); return; @@ -52,12 +112,9 @@ void ModePageDevice::ModeSense10(SASIDEV *controller) controller->DataIn(); } -bool ModePageDevice::ModeSelect(const DWORD* /*cdb*/, const BYTE *buf, int length) +bool ModePageDevice::ModeSelect(const DWORD*, const BYTE *, int) { - ASSERT(buf); - ASSERT(length >= 0); - - // cannot be set + // Cannot be set SetStatusCode(STATUS_INVALIDPRM); return false; @@ -67,7 +124,7 @@ void ModePageDevice::ModeSelect6(SASIDEV *controller) { LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, ctrl->buffer[0]); - ctrl->length = ModeSelectCheck6(ctrl->cmd); + ctrl->length = ModeSelectCheck6(); if (ctrl->length <= 0) { controller->Error(); return; @@ -80,7 +137,7 @@ void ModePageDevice::ModeSelect10(SASIDEV *controller) { LOGTRACE("%s Unsupported mode page $%02X", __PRETTY_FUNCTION__, ctrl->buffer[0]); - ctrl->length = ModeSelectCheck10(ctrl->cmd); + ctrl->length = ModeSelectCheck10(); if (ctrl->length <= 0) { controller->Error(); return; @@ -89,11 +146,11 @@ void ModePageDevice::ModeSelect10(SASIDEV *controller) controller->DataOut(); } -int ModePageDevice::ModeSelectCheck(const DWORD *cdb, int length) +int ModePageDevice::ModeSelectCheck(int length) { // Error if save parameters are set for other types than of SCHD or SCRM - // TODO This assumption is not correct, and this code should be located elsewhere - if (!IsSCSIHD() && (cdb[1] & 0x01)) { + // TODO The assumption above is not correct, and this code should be located elsewhere + if (!IsSCSIHD() && (ctrl->cmd[1] & 0x01)) { SetStatusCode(STATUS_INVALIDCDB); return 0; } @@ -101,21 +158,21 @@ int ModePageDevice::ModeSelectCheck(const DWORD *cdb, int length) return length; } -int ModePageDevice::ModeSelectCheck6(const DWORD *cdb) +int ModePageDevice::ModeSelectCheck6() { // Receive the data specified by the parameter length - return ModeSelectCheck(cdb, cdb[4]); + return ModeSelectCheck(ctrl->cmd[4]); } -int ModePageDevice::ModeSelectCheck10(const DWORD *cdb) +int ModePageDevice::ModeSelectCheck10() { // Receive the data specified by the parameter length - int length = cdb[7]; + int length = ctrl->cmd[7]; length <<= 8; - length |= cdb[8]; - if (length > 0x800) { - length = 0x800; + length |= ctrl->cmd[8]; + if (length > ctrl->bufsize) { + length = ctrl->bufsize; } - return ModeSelectCheck(cdb, length); + return ModeSelectCheck(length); } diff --git a/src/raspberrypi/devices/mode_page_device.h b/src/raspberrypi/devices/mode_page_device.h index 3b50c236..19ec9db0 100644 --- a/src/raspberrypi/devices/mode_page_device.h +++ b/src/raspberrypi/devices/mode_page_device.h @@ -11,6 +11,8 @@ #include "primary_device.h" #include +#include +#include using namespace std; @@ -24,11 +26,16 @@ public: virtual bool Dispatch(SCSIDEV *) override; virtual int ModeSense6(const DWORD *, BYTE *) = 0; - virtual int ModeSense10(const DWORD *, BYTE *) = 0; + virtual int ModeSense10(const DWORD *, BYTE *, int) = 0; // TODO This method should not be called by SASIDEV virtual bool ModeSelect(const DWORD *, const BYTE *, int); +protected: + + int AddModePages(const DWORD *, BYTE *, int); + virtual void AddModePages(map>&, int, bool) const = 0; + private: typedef PrimaryDevice super; @@ -40,7 +47,7 @@ private: void ModeSelect6(SASIDEV *); void ModeSelect10(SASIDEV *); - int ModeSelectCheck(const DWORD *, int); - int ModeSelectCheck6(const DWORD *); - int ModeSelectCheck10(const DWORD *); + int ModeSelectCheck(int); + int ModeSelectCheck6(); + int ModeSelectCheck10(); }; diff --git a/src/raspberrypi/devices/primary_device.cpp b/src/raspberrypi/devices/primary_device.cpp index 9e3b3122..cad1212f 100644 --- a/src/raspberrypi/devices/primary_device.cpp +++ b/src/raspberrypi/devices/primary_device.cpp @@ -68,11 +68,6 @@ void PrimaryDevice::ReportLuns(SASIDEV *controller) { BYTE *buf = ctrl->buffer; - if (!CheckReady()) { - controller->Error(); - return; - } - int allocation_length = (ctrl->cmd[6] << 24) + (ctrl->cmd[7] << 16) + (ctrl->cmd[8] << 8) + ctrl->cmd[9]; memset(buf, 0, allocation_length); @@ -111,7 +106,7 @@ void PrimaryDevice::RequestSense(SASIDEV *controller) } ctrl->length = ((PrimaryDevice *)ctrl->unit[lun])->RequestSense(ctrl->cmd, ctrl->buffer); - ASSERT(ctrl->length > 0); + assert(ctrl->length > 0); LOGTRACE("%s Status $%02X, Sense Key $%02X, ASC $%02X",__PRETTY_FUNCTION__, ctrl->status, ctrl->buffer[2], ctrl->buffer[12]); @@ -124,7 +119,7 @@ bool PrimaryDevice::CheckReady() if (IsReset()) { SetStatusCode(STATUS_DEVRESET); SetReset(false); - LOGTRACE("%s Disk in reset", __PRETTY_FUNCTION__); + LOGTRACE("%s Device in reset", __PRETTY_FUNCTION__); return false; } @@ -132,26 +127,32 @@ bool PrimaryDevice::CheckReady() if (IsAttn()) { SetStatusCode(STATUS_ATTENTION); SetAttn(false); - LOGTRACE("%s Disk in needs attention", __PRETTY_FUNCTION__); + LOGTRACE("%s Device in needs attention", __PRETTY_FUNCTION__); return false; } // Return status if not ready if (!IsReady()) { SetStatusCode(STATUS_NOTREADY); - LOGTRACE("%s Disk not ready", __PRETTY_FUNCTION__); + LOGTRACE("%s Device not ready", __PRETTY_FUNCTION__); return false; } // Initialization with no error - LOGTRACE("%s Disk is ready", __PRETTY_FUNCTION__); + LOGTRACE("%s Device is ready", __PRETTY_FUNCTION__); return true; } int PrimaryDevice::Inquiry(int type, int scsi_level, bool is_removable, const DWORD *cdb, BYTE *buf) { - int allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8); + // EVPD and page code check + if ((cdb[1] & 0x01) || cdb[2]) { + SetStatusCode(STATUS_INVALIDCDB); + return 0; + } + + int allocation_length = cdb[4] + (cdb[3] << 8); if (allocation_length > 4) { if (allocation_length > 44) { allocation_length = 44; @@ -167,6 +168,8 @@ int PrimaryDevice::Inquiry(int type, int scsi_level, bool is_removable, const DW buf[0] = type; buf[1] = is_removable ? 0x80 : 0x00; buf[2] = scsi_level; + // Response data format is SCSI-2 for devices supporting SCSI-2 or newer, otherwise it is SCSI-1-CCS + buf[3] = scsi_level >= 2 ? 2 : 0; buf[4] = 0x1F; // Padded vendor, product, revision @@ -178,22 +181,16 @@ int PrimaryDevice::Inquiry(int type, int scsi_level, bool is_removable, const DW int PrimaryDevice::RequestSense(const DWORD *cdb, BYTE *buf) { - ASSERT(cdb); - ASSERT(buf); - // Return not ready only if there are no errors - if (GetStatusCode() == STATUS_NOERROR) { - if (!IsReady()) { - SetStatusCode(STATUS_NOTREADY); - } + if (GetStatusCode() == STATUS_NOERROR && !IsReady()) { + SetStatusCode(STATUS_NOTREADY); } // Size determination (according to allocation length) int size = (int)cdb[4]; - ASSERT((size >= 0) && (size < 0x100)); + assert(size >= 0 && size < 0x100); // For SCSI-1, transfer 4 bytes when the size is 0 - // (Deleted this specification for SCSI-2) if (size == 0) { size = 4; } diff --git a/src/raspberrypi/devices/primary_device.h b/src/raspberrypi/devices/primary_device.h index c986bc19..c8923fee 100644 --- a/src/raspberrypi/devices/primary_device.h +++ b/src/raspberrypi/devices/primary_device.h @@ -37,6 +37,7 @@ public: virtual int Inquiry(const DWORD *, BYTE *) = 0; virtual int RequestSense(const DWORD *, BYTE *); virtual bool WriteBytes(BYTE *, uint32_t); + virtual int GetSendDelay() { return BUS::SEND_NO_DELAY; } protected: diff --git a/src/raspberrypi/devices/sasihd.cpp b/src/raspberrypi/devices/sasihd.cpp index be8293d2..463eda6b 100644 --- a/src/raspberrypi/devices/sasihd.cpp +++ b/src/raspberrypi/devices/sasihd.cpp @@ -19,26 +19,11 @@ #include "exceptions.h" #include "../config.h" -//=========================================================================== -// -// SASI Hard Disk -// -//=========================================================================== - -//--------------------------------------------------------------------------- -// -// Constructor -// -//--------------------------------------------------------------------------- -SASIHD::SASIHD() : Disk("SAHD") +SASIHD::SASIHD(const set& sector_sizes) : Disk("SAHD") { + SetSectorSizes(sector_sizes); } -//--------------------------------------------------------------------------- -// -// Reset -// -//--------------------------------------------------------------------------- void SASIHD::Reset() { // Unlock, clear attention @@ -50,14 +35,9 @@ void SASIHD::Reset() SetStatusCode(STATUS_NOERROR); } -//--------------------------------------------------------------------------- -// -// Open -// -//--------------------------------------------------------------------------- void SASIHD::Open(const Filepath& path) { - ASSERT(!IsReady()); + assert(!IsReady()); // Open as read-only Fileio fio; @@ -101,30 +81,17 @@ void SASIHD::Open(const Filepath& path) FileSupport::SetPath(path); } -//--------------------------------------------------------------------------- -// -// INQUIRY -// -//--------------------------------------------------------------------------- int SASIHD::Inquiry(const DWORD* /*cdb*/, BYTE* /*buf*/) { SetStatusCode(STATUS_INVALIDCMD); return 0; } -//--------------------------------------------------------------------------- -// -// REQUEST SENSE -// -//--------------------------------------------------------------------------- int SASIHD::RequestSense(const DWORD *cdb, BYTE *buf) { - ASSERT(cdb); - ASSERT(buf); - // Size decision int size = (int)cdb[4]; - ASSERT(size >= 0 && size < 0x100); + assert(size >= 0 && size < 0x100); // Transfer 4 bytes when size 0 (Shugart Associates System Interface specification) if (size == 0) { diff --git a/src/raspberrypi/devices/sasihd.h b/src/raspberrypi/devices/sasihd.h index a553fcac..c802364b 100644 --- a/src/raspberrypi/devices/sasihd.h +++ b/src/raspberrypi/devices/sasihd.h @@ -27,8 +27,8 @@ class SASIHD : public Disk, public FileSupport { public: - SASIHD(); - ~SASIHD() {}; + SASIHD(const set&); + ~SASIHD() {} void Reset(); void Open(const Filepath& path) override; diff --git a/src/raspberrypi/devices/scsi_daynaport.cpp b/src/raspberrypi/devices/scsi_daynaport.cpp index f70b6e7f..4094fbcc 100644 --- a/src/raspberrypi/devices/scsi_daynaport.cpp +++ b/src/raspberrypi/devices/scsi_daynaport.cpp @@ -583,3 +583,11 @@ void SCSIDaynaPort::EnableInterface(SASIDEV *controller) controller->Status(); } + +int SCSIDaynaPort::GetSendDelay() +{ + // The Daynaport needs to have a delay after the size/flags field + // of the read response. In the MacOS driver, it looks like the + // driver is doing two "READ" system calls. + return DAYNAPORT_READ_HEADER_SZ; +} diff --git a/src/raspberrypi/devices/scsi_daynaport.h b/src/raspberrypi/devices/scsi_daynaport.h index 1dbbef60..cda2cb0c 100644 --- a/src/raspberrypi/devices/scsi_daynaport.h +++ b/src/raspberrypi/devices/scsi_daynaport.h @@ -67,6 +67,7 @@ public: void SetInterfaceMode(SASIDEV *); void SetMcastAddr(SASIDEV *); void EnableInterface(SASIDEV *); + int GetSendDelay() override; bool Dispatch(SCSIDEV *) override; diff --git a/src/raspberrypi/devices/scsi_host_bridge.cpp b/src/raspberrypi/devices/scsi_host_bridge.cpp index d9be4579..d0dbb8c7 100644 --- a/src/raspberrypi/devices/scsi_host_bridge.cpp +++ b/src/raspberrypi/devices/scsi_host_bridge.cpp @@ -121,7 +121,7 @@ int SCSIBR::Inquiry(const DWORD *cdb, BYTE *buf) buf[0] = 0x09; buf[2] = 0x02; buf[3] = 0x02; - buf[4] = 36 - 5 + 8; // required + 8 byte extension + buf[4] = 0x1F + 8; // required + 8 byte extension // Padded vendor, product, revision memcpy(&buf[8], GetPaddedName().c_str(), 28); @@ -152,13 +152,9 @@ int SCSIBR::Inquiry(const DWORD *cdb, BYTE *buf) void SCSIBR::TestUnitReady(SASIDEV *controller) { // Always successful - controller->Status();} + controller->Status(); +} -//--------------------------------------------------------------------------- -// -// GET MESSAGE(10) -// -//--------------------------------------------------------------------------- int SCSIBR::GetMessage10(const DWORD *cdb, BYTE *buf) { // Type @@ -239,16 +235,8 @@ int SCSIBR::GetMessage10(const DWORD *cdb, BYTE *buf) return 0; } -//--------------------------------------------------------------------------- -// -// SEND MESSAGE(10) -// -//--------------------------------------------------------------------------- bool SCSIBR::SendMessage10(const DWORD *cdb, BYTE *buf) { - ASSERT(cdb); - ASSERT(buf); - // Type int type = cdb[2]; @@ -301,11 +289,6 @@ bool SCSIBR::SendMessage10(const DWORD *cdb, BYTE *buf) return false; } -//--------------------------------------------------------------------------- -// -// GET MESSAGE(10) -// -//--------------------------------------------------------------------------- void SCSIBR::GetMessage10(SASIDEV *controller) { // Reallocate buffer (because it is not transfer for each block) @@ -365,41 +348,22 @@ void SCSIBR::SendMessage10(SASIDEV *controller) controller->DataOut(); } -//--------------------------------------------------------------------------- -// -// Get MAC Address -// -//--------------------------------------------------------------------------- int SCSIBR::GetMacAddr(BYTE *mac) { - ASSERT(mac); - memcpy(mac, mac_addr, 6); return 6; } -//--------------------------------------------------------------------------- -// -// Set MAC Address -// -//--------------------------------------------------------------------------- void SCSIBR::SetMacAddr(BYTE *mac) { - ASSERT(mac); - memcpy(mac_addr, mac, 6); } -//--------------------------------------------------------------------------- -// -// Receive Packet -// -//--------------------------------------------------------------------------- void SCSIBR::ReceivePacket() { static const BYTE bcast_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - ASSERT(tap); + assert(tap); // previous packet has not been received if (packet_enable) { @@ -429,15 +393,9 @@ void SCSIBR::ReceivePacket() } } -//--------------------------------------------------------------------------- -// -// Get Packet -// -//--------------------------------------------------------------------------- void SCSIBR::GetPacketBuf(BYTE *buf) { - ASSERT(tap); - ASSERT(buf); + assert(tap); // Size limit int len = packet_len; @@ -452,15 +410,9 @@ void SCSIBR::GetPacketBuf(BYTE *buf) packet_enable = false; } -//--------------------------------------------------------------------------- -// -// Send Packet -// -//--------------------------------------------------------------------------- void SCSIBR::SendPacket(BYTE *buf, int len) { - ASSERT(tap); - ASSERT(buf); + assert(tap); tap->Tx(buf, len); } @@ -472,9 +424,6 @@ void SCSIBR::SendPacket(BYTE *buf, int len) //--------------------------------------------------------------------------- void SCSIBR::FS_InitDevice(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - fs->Reset(); fsresult = fs->InitDevice((Human68k::argument_t*)buf); } @@ -486,13 +435,9 @@ void SCSIBR::FS_InitDevice(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_CheckDir(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i]; i += sizeof(Human68k::namests_t); @@ -507,13 +452,9 @@ void SCSIBR::FS_CheckDir(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_MakeDir(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i]; i += sizeof(Human68k::namests_t); @@ -528,13 +469,9 @@ void SCSIBR::FS_MakeDir(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_RemoveDir(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i]; i += sizeof(Human68k::namests_t); @@ -549,13 +486,9 @@ void SCSIBR::FS_RemoveDir(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Rename(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i]; i += sizeof(Human68k::namests_t); @@ -573,13 +506,9 @@ void SCSIBR::FS_Rename(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Delete(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i]; i += sizeof(Human68k::namests_t); @@ -594,13 +523,9 @@ void SCSIBR::FS_Delete(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Attribute(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); Human68k::namests_t *pNamests = (Human68k::namests_t*)&buf[i]; i += sizeof(Human68k::namests_t); @@ -619,13 +544,9 @@ void SCSIBR::FS_Attribute(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Files(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); dp = (DWORD*)&buf[i]; DWORD nKey = ntohl(*dp); @@ -665,13 +586,9 @@ void SCSIBR::FS_Files(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_NFiles(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); dp = (DWORD*)&buf[i]; DWORD nKey = ntohl(*dp); @@ -708,13 +625,9 @@ void SCSIBR::FS_NFiles(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Create(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); dp = (DWORD*)&buf[i]; DWORD nKey = ntohl(*dp); @@ -762,13 +675,9 @@ void SCSIBR::FS_Create(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Open(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); dp = (DWORD*)&buf[i]; DWORD nKey = ntohl(*dp); @@ -808,13 +717,9 @@ void SCSIBR::FS_Open(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Close(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); dp = (DWORD*)&buf[i]; DWORD nKey = ntohl(*dp); @@ -851,13 +756,9 @@ void SCSIBR::FS_Close(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Read(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nKey = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); Human68k::fcb_t *pFcb = (Human68k::fcb_t*)&buf[i]; i += sizeof(Human68k::fcb_t); @@ -896,13 +797,9 @@ void SCSIBR::FS_Read(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Write(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nKey = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); Human68k::fcb_t *pFcb = (Human68k::fcb_t*)&buf[i]; i += sizeof(Human68k::fcb_t); @@ -939,13 +836,9 @@ void SCSIBR::FS_Write(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Seek(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nKey = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); Human68k::fcb_t *pFcb = (Human68k::fcb_t*)&buf[i]; i += sizeof(Human68k::fcb_t); @@ -986,13 +879,9 @@ void SCSIBR::FS_Seek(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_TimeStamp(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); dp = (DWORD*)&buf[i]; DWORD nKey = ntohl(*dp); @@ -1033,9 +922,6 @@ void SCSIBR::FS_TimeStamp(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_GetCapacity(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); @@ -1058,13 +944,9 @@ void SCSIBR::FS_GetCapacity(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_CtrlDrive(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); Human68k::ctrldrive_t *pCtrlDrive = (Human68k::ctrldrive_t*)&buf[i]; @@ -1081,9 +963,6 @@ void SCSIBR::FS_CtrlDrive(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_GetDPB(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); @@ -1108,13 +987,9 @@ void SCSIBR::FS_GetDPB(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_DiskRead(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); dp = (DWORD*)&buf[i]; DWORD nSector = ntohl(*dp); @@ -1135,9 +1010,6 @@ void SCSIBR::FS_DiskRead(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_DiskWrite(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); @@ -1151,13 +1023,9 @@ void SCSIBR::FS_DiskWrite(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Ioctrl(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - - int i = 0; DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); - i += sizeof(DWORD); + int i = sizeof(DWORD); dp = (DWORD*)&buf[i]; DWORD nFunction = ntohl(*dp); @@ -1198,9 +1066,6 @@ void SCSIBR::FS_Ioctrl(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Flush(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); @@ -1214,9 +1079,6 @@ void SCSIBR::FS_Flush(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_CheckMedia(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); @@ -1230,9 +1092,6 @@ void SCSIBR::FS_CheckMedia(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::FS_Lock(BYTE *buf) { - ASSERT(fs); - ASSERT(buf); - DWORD *dp = (DWORD*)buf; DWORD nUnit = ntohl(*dp); @@ -1246,8 +1105,6 @@ void SCSIBR::FS_Lock(BYTE *buf) //--------------------------------------------------------------------------- int SCSIBR::ReadFsResult(BYTE *buf) { - ASSERT(buf); - DWORD *dp = (DWORD*)buf; *dp = htonl(fsresult); return sizeof(DWORD); @@ -1260,8 +1117,6 @@ int SCSIBR::ReadFsResult(BYTE *buf) //--------------------------------------------------------------------------- int SCSIBR::ReadFsOut(BYTE *buf) { - ASSERT(buf); - memcpy(buf, fsout, fsoutlen); return fsoutlen; } @@ -1273,8 +1128,6 @@ int SCSIBR::ReadFsOut(BYTE *buf) //--------------------------------------------------------------------------- int SCSIBR::ReadFsOpt(BYTE *buf) { - ASSERT(buf); - memcpy(buf, fsopt, fsoptlen); return fsoptlen; } @@ -1286,8 +1139,6 @@ int SCSIBR::ReadFsOpt(BYTE *buf) //--------------------------------------------------------------------------- void SCSIBR::WriteFs(int func, BYTE *buf) { - ASSERT(buf); - fsresult = FS_FATAL_INVALIDCOMMAND; fsoutlen = 0; fsoptlen = 0; diff --git a/src/raspberrypi/devices/scsi_printer.cpp b/src/raspberrypi/devices/scsi_printer.cpp index 066eb4ac..e340ac6d 100644 --- a/src/raspberrypi/devices/scsi_printer.cpp +++ b/src/raspberrypi/devices/scsi_printer.cpp @@ -17,7 +17,8 @@ // 2. The client sends the data to be printed with one or several PRINT commands. Due to // https://github.com/akuker/RASCSI/issues/669 the maximum transfer size per PRINT command is // limited to 4096 bytes. -// 3. The client triggers printing with SYNCHRONIZE BUFFER. +// 3. The client triggers printing with SYNCHRONIZE BUFFER. Each SYNCHRONIZE BUFFER results in +// the print command for this printer (see below) to be called for the data not yet printed. // 4. The client releases the printer with RELEASE UNIT (optional step, mandatory for a // multi-initiator environment). // @@ -68,7 +69,7 @@ SCSIPrinter::SCSIPrinter() : PrimaryDevice("SCLP"), ScsiPrinterCommands() SCSIPrinter::~SCSIPrinter() { - DiscardReservation(); + Cleanup(); } bool SCSIPrinter::Init(const map& params) @@ -168,7 +169,7 @@ void SCSIPrinter::Print(SCSIDEV *controller) // TODO This device suffers from the statically allocated buffer size, // see https://github.com/akuker/RASCSI/issues/669 - if (length > (uint32_t)controller->DEFAULT_BUFFER_SIZE) { + if (length > (uint32_t)ctrl->bufsize) { LOGERROR("Transfer buffer overflow"); controller->Error(ERROR_CODES::sense_key::ILLEGAL_REQUEST, ERROR_CODES::asc::INVALID_FIELD_IN_CDB); diff --git a/src/raspberrypi/devices/scsicd.cpp b/src/raspberrypi/devices/scsicd.cpp index c2658dff..b5b16b34 100644 --- a/src/raspberrypi/devices/scsicd.cpp +++ b/src/raspberrypi/devices/scsicd.cpp @@ -176,8 +176,10 @@ bool CDTrack::IsAudio() const // //=========================================================================== -SCSICD::SCSICD() : Disk("SCCD"), ScsiMmcCommands(), FileSupport() +SCSICD::SCSICD(const set& sector_sizes) : Disk("SCCD"), ScsiMmcCommands(), FileSupport() { + SetSectorSizes(sector_sizes); + // NOT in raw format rawfile = false; @@ -262,7 +264,7 @@ void SCSICD::Open(const Filepath& path) // Successful opening ASSERT(GetBlockCount() > 0); - Disk::Open(path); + super::Open(path); FileSupport::SetPath(path); // Set RAW flag @@ -414,7 +416,7 @@ int SCSICD::Inquiry(const DWORD *cdb, BYTE *buf) buf[1] = 0x80; buf[2] = 0x02; buf[3] = 0x02; - buf[4] = 36 - 5; // Required + buf[4] = 0x1F; // Fill with blanks memset(&buf[8], 0x20, buf[4] - 3); @@ -456,6 +458,48 @@ int SCSICD::Inquiry(const DWORD *cdb, BYTE *buf) return size; } +void SCSICD::AddModePages(map>& pages, int page, bool changeable) const +{ + super::AddModePages(pages, page, changeable); + + // Page code 13 + if (page == 0x0d || page == 0x3f) { + AddCDROMPage(pages, changeable); + } + + // Page code 14 + if (page == 0x0e || page == 0x3f) { + AddCDDAPage(pages, changeable); + } +} + +void SCSICD::AddCDROMPage(map>& pages, bool changeable) const +{ + vector buf(8); + + // No changeable area + if (!changeable) { + // 2 seconds for inactive timer + buf[3] = 0x05; + + // MSF multiples are 60 and 75 respectively + buf[5] = 60; + buf[7] = 75; + } + + pages[13] = buf; +} + +void SCSICD::AddCDDAPage(map>& pages, bool) const +{ + vector buf(16); + + // Audio waits for operation completion and allows + // PLAY across multiple tracks + + pages[14] = buf; +} + int SCSICD::Read(const DWORD *cdb, BYTE *buf, uint64_t block) { ASSERT(buf); @@ -497,7 +541,7 @@ int SCSICD::Read(const DWORD *cdb, BYTE *buf, uint64_t block) // Base class ASSERT(dataindex >= 0); - return Disk::Read(cdb, buf, block); + return super::Read(cdb, buf, block); } int SCSICD::ReadToc(const DWORD *cdb, BYTE *buf) diff --git a/src/raspberrypi/devices/scsicd.h b/src/raspberrypi/devices/scsicd.h index 42150b5c..b22f398d 100644 --- a/src/raspberrypi/devices/scsicd.h +++ b/src/raspberrypi/devices/scsicd.h @@ -76,7 +76,7 @@ public: TrackMax = 96 // Maximum number of tracks }; - SCSICD(); + SCSICD(const set&); ~SCSICD(); bool Dispatch(SCSIDEV *) override; @@ -88,11 +88,18 @@ public: int Read(const DWORD *cdb, BYTE *buf, uint64_t block) override; // READ command int ReadToc(const DWORD *cdb, BYTE *buf); // READ TOC command +protected: + + void AddModePages(map>&, int, bool) const override; + private: typedef Disk super; Dispatcher dispatcher; + void AddCDROMPage(map>&, bool) const; + void AddCDDAPage(map>&, bool) const; + // Open void OpenCue(const Filepath& path); // Open(CUE) void OpenIso(const Filepath& path); // Open(ISO) diff --git a/src/raspberrypi/devices/scsihd.cpp b/src/raspberrypi/devices/scsihd.cpp index 4451c0dc..6a0cc194 100644 --- a/src/raspberrypi/devices/scsihd.cpp +++ b/src/raspberrypi/devices/scsihd.cpp @@ -26,8 +26,9 @@ // //=========================================================================== -SCSIHD::SCSIHD(bool removable) : Disk(removable ? "SCRM" : "SCHD") +SCSIHD::SCSIHD(const set& sector_sizes, bool removable) : Disk(removable ? "SCRM" : "SCHD") { + SetSectorSizes(sector_sizes); } void SCSIHD::FinalizeSetup(const Filepath &path, off_t size) @@ -75,7 +76,7 @@ void SCSIHD::Reset() void SCSIHD::Open(const Filepath& path) { - ASSERT(!IsReady()); + assert(!IsReady()); // Open as read-only Fileio fio; @@ -105,12 +106,6 @@ int SCSIHD::Inquiry(const DWORD *cdb, BYTE *buf) return 0; } - // Ready check (Error if no image file) - if (!IsReady()) { - SetStatusCode(STATUS_NOTREADY); - return 0; - } - // Basic data // buf[0] ... Direct Access Device // buf[1] ... Bit 7 set means removable @@ -121,7 +116,7 @@ int SCSIHD::Inquiry(const DWORD *cdb, BYTE *buf) buf[1] = IsRemovable() ? 0x80 : 0x00; buf[2] = 0x02; buf[3] = 0x02; - buf[4] = 28 + 3; // Value close to real HDD + buf[4] = 0x1F; // Padded vendor, product, revision memcpy(&buf[8], GetPaddedName().c_str(), 28); @@ -139,10 +134,9 @@ int SCSIHD::Inquiry(const DWORD *cdb, BYTE *buf) bool SCSIHD::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) { - int size; + assert(length >= 0); - ASSERT(buf); - ASSERT(length >= 0); + int size; // PF if (cdb[1] & 0x10) { @@ -216,23 +210,19 @@ bool SCSIHD::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) // Add Vendor special page to make drive Apple compatible // //--------------------------------------------------------------------------- -int SCSIHD::AddVendorPage(int page, bool change, BYTE *buf) +void SCSIHD::AddVendorPage(map>& pages, int page, bool changeable) const { - ASSERT(buf); - - // Page code 48 or 63 + // Page code 48 if (page != 0x30 && page != 0x3f) { - return 0; + return; } - // Set the message length - buf[0] = 0x30; - buf[1] = 0x1c; + vector buf(30); // No changeable area - if (!change) { - memcpy(&buf[0xa], "APPLE COMPUTER, INC.", 20); + if (!changeable) { + memcpy(&buf.data()[0xa], "APPLE COMPUTER, INC.", 20); } - return 30; + pages[48] = buf; } diff --git a/src/raspberrypi/devices/scsihd.h b/src/raspberrypi/devices/scsihd.h index 7bafb2f9..128578f5 100644 --- a/src/raspberrypi/devices/scsihd.h +++ b/src/raspberrypi/devices/scsihd.h @@ -22,8 +22,8 @@ class SCSIHD : public Disk, public FileSupport { public: - SCSIHD(bool); - virtual ~SCSIHD() {}; + SCSIHD(const set&, bool); + virtual ~SCSIHD() {} void FinalizeSetup(const Filepath&, off_t); @@ -34,6 +34,5 @@ public: virtual int Inquiry(const DWORD *cdb, BYTE *buf) override; bool ModeSelect(const DWORD *cdb, const BYTE *buf, int length) override; - // Add vendor special page - int AddVendorPage(int page, bool change, BYTE *buf) override; + void AddVendorPage(map>&, int, bool) const override; }; diff --git a/src/raspberrypi/devices/scsihd_nec.cpp b/src/raspberrypi/devices/scsihd_nec.cpp index 0302b7dd..02b93eae 100644 --- a/src/raspberrypi/devices/scsihd_nec.cpp +++ b/src/raspberrypi/devices/scsihd_nec.cpp @@ -18,7 +18,7 @@ #include "fileio.h" #include "exceptions.h" -SCSIHD_NEC::SCSIHD_NEC() : SCSIHD(false) +SCSIHD_NEC::SCSIHD_NEC(const set& sector_sizes) : SCSIHD(sector_sizes, false) { // Work initialization cylinders = 0; @@ -146,31 +146,30 @@ int SCSIHD_NEC::Inquiry(const DWORD *cdb, BYTE *buf) return size; } -int SCSIHD_NEC::AddErrorPage(bool change, BYTE *buf) +void SCSIHD_NEC::AddErrorPage(map>& pages, bool) const { - ASSERT(buf); - - // Set the message length - buf[0] = 0x01; - buf[1] = 0x06; + vector buf(8); // The retry count is 0, and the limit time uses the default value inside the device. - return 8; + + pages[1] = buf; } -int SCSIHD_NEC::AddFormatPage(bool change, BYTE *buf) +void SCSIHD_NEC::AddFormatPage(map>& pages, bool changeable) const { - ASSERT(buf); + vector buf(24); - // Set the message length - buf[0] = 0x80 | 0x03; - buf[1] = 0x16; + // Page can be saved + buf[0] = 0x80; // Make the number of bytes in the physical sector appear mutable (although it cannot actually be) - if (change) { + if (changeable) { buf[0xc] = 0xff; buf[0xd] = 0xff; - return 24; + + pages[3] = buf; + + return; } if (IsReady()) { @@ -193,19 +192,15 @@ int SCSIHD_NEC::AddFormatPage(bool change, BYTE *buf) buf[20] = 0x20; } - return 24; + pages[3] = buf; } -int SCSIHD_NEC::AddDrivePage(bool change, BYTE *buf) +void SCSIHD_NEC::AddDrivePage(map>& pages, bool changeable) const { - ASSERT(buf); - - // Set the message length - buf[0] = 0x04; - buf[1] = 0x12; + vector buf(20); // No changeable area - if (!change && IsReady()) { + if (!changeable && IsReady()) { // Set the number of cylinders buf[0x2] = (BYTE)(cylinders >> 16); buf[0x3] = (BYTE)(cylinders >> 8); @@ -215,5 +210,5 @@ int SCSIHD_NEC::AddDrivePage(bool change, BYTE *buf) buf[0x5] = (BYTE)heads; } - return 20; + pages[4] = buf; } diff --git a/src/raspberrypi/devices/scsihd_nec.h b/src/raspberrypi/devices/scsihd_nec.h index 82e2baa7..75923123 100644 --- a/src/raspberrypi/devices/scsihd_nec.h +++ b/src/raspberrypi/devices/scsihd_nec.h @@ -25,17 +25,17 @@ class SCSIHD_NEC : public SCSIHD { public: - SCSIHD_NEC(); - ~SCSIHD_NEC() {}; + SCSIHD_NEC(const set&); + ~SCSIHD_NEC() {} void Open(const Filepath& path) override; // Commands int Inquiry(const DWORD *cdb, BYTE *buf) override; - int AddErrorPage(bool change, BYTE *buf) override; - int AddFormatPage(bool change, BYTE *buf) override; - int AddDrivePage(bool change, BYTE *buf) override; + void AddErrorPage(map>&, bool) const override; + void AddFormatPage(map>&, bool) const override; + void AddDrivePage(map>&, bool) const override; private: // Geometry data diff --git a/src/raspberrypi/devices/scsimo.cpp b/src/raspberrypi/devices/scsimo.cpp index 75d1bc2c..0bed7926 100644 --- a/src/raspberrypi/devices/scsimo.cpp +++ b/src/raspberrypi/devices/scsimo.cpp @@ -19,29 +19,15 @@ #include "fileio.h" #include "exceptions.h" -//=========================================================================== -// -// SCSI magneto-optical disk -// -//=========================================================================== - -//--------------------------------------------------------------------------- -// -// Constructor -// -//--------------------------------------------------------------------------- -SCSIMO::SCSIMO() : Disk("SCMO") +SCSIMO::SCSIMO(const set& sector_sizes, const map& geometries) : Disk("SCMO") { + SetSectorSizes(sector_sizes); + SetGeometries(geometries); } -//--------------------------------------------------------------------------- -// -// Open -// -//--------------------------------------------------------------------------- void SCSIMO::Open(const Filepath& path) { - ASSERT(!IsReady()); + assert(!IsReady()); // Open as read-only Fileio fio; @@ -77,16 +63,8 @@ void SCSIMO::Open(const Filepath& path) } } -//--------------------------------------------------------------------------- -// -// INQUIRY -// -//--------------------------------------------------------------------------- int SCSIMO::Inquiry(const DWORD *cdb, BYTE *buf) { - ASSERT(cdb); - ASSERT(buf); - // EVPD check if (cdb[1] & 0x01) { SetStatusCode(STATUS_INVALIDCDB); @@ -104,7 +82,7 @@ int SCSIMO::Inquiry(const DWORD *cdb, BYTE *buf) buf[1] = 0x80; buf[2] = 0x02; buf[3] = 0x02; - buf[4] = 36 - 5; // required + buf[4] = 0x1F; // Padded vendor, product, revision memcpy(&buf[8], GetPaddedName().c_str(), 28); @@ -120,16 +98,36 @@ int SCSIMO::Inquiry(const DWORD *cdb, BYTE *buf) return size; } -//--------------------------------------------------------------------------- -// -// MODE SELECT -// -//--------------------------------------------------------------------------- +void SCSIMO::SetDeviceParameters(BYTE *buf) +{ + Disk::SetDeviceParameters(buf); + + // MEDIUM TYPE: Optical reversible or erasable + buf[2] = 0x03; +} + +void SCSIMO::AddModePages(map>& pages, int page, bool changeable) const +{ + Disk::AddModePages(pages, page, changeable); + + // Page code 6 + if (page == 0x06 || page == 0x3f) { + AddOptionPage(pages, changeable); + } +} + +void SCSIMO::AddOptionPage(map>& pages, bool) const +{ + vector buf(4); + pages[6] = buf; + + // Do not report update blocks +} + bool SCSIMO::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) { int size; - ASSERT(buf); ASSERT(length >= 0); // PF @@ -191,22 +189,20 @@ bool SCSIMO::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) // Vendor Unique Format Page 20h (MO) // //--------------------------------------------------------------------------- -int SCSIMO::AddVendor(int page, BOOL change, BYTE *buf) +void SCSIMO::AddVendorPage(map>& pages, int page, bool changeable) const { - ASSERT(buf); - // Page code 20h - if ((page != 0x20) && (page != 0x3f)) { - return 0; + if (page != 0x20 && page != 0x3f) { + return; } - // Set the message length - buf[0] = 0x20; - buf[1] = 0x0a; + vector buf(12); // No changeable area - if (change) { - return 12; + if (changeable) { + pages[32] = buf; + + return; } /* @@ -287,5 +283,7 @@ int SCSIMO::AddVendor(int page, BOOL change, BYTE *buf) buf[11] = (BYTE)bands; } - return 12; + pages[32] = buf; + + return; } diff --git a/src/raspberrypi/devices/scsimo.h b/src/raspberrypi/devices/scsimo.h index 3ed4738c..b55d42ea 100644 --- a/src/raspberrypi/devices/scsimo.h +++ b/src/raspberrypi/devices/scsimo.h @@ -22,8 +22,8 @@ class SCSIMO : public Disk, public FileSupport { public: - SCSIMO(); - ~SCSIMO() {}; + SCSIMO(const set&, const map&); + ~SCSIMO() {} void Open(const Filepath& path) override; @@ -31,6 +31,14 @@ public: int Inquiry(const DWORD *cdb, BYTE *buf) override; bool ModeSelect(const DWORD *cdb, const BYTE *buf, int length) override; +protected: + // Internal processing - int AddVendor(int page, BOOL change, BYTE *buf); // Add vendor special page + void SetDeviceParameters(BYTE *) override; + void AddModePages(map>&, int, bool) const override; + void AddVendorPage(map>&, int, bool) const override; + +private: + + void AddOptionPage(map>&, bool) const; }; diff --git a/src/raspberrypi/gpiobus.h b/src/raspberrypi/gpiobus.h index 78b01b54..622cc493 100644 --- a/src/raspberrypi/gpiobus.h +++ b/src/raspberrypi/gpiobus.h @@ -488,7 +488,7 @@ public: // Bus signal acquisition // //--------------------------------------------------------------------------- - inline DWORD Aquire() + inline DWORD Aquire() override { #if defined(__x86_64__) || defined(__X86__) // Only used for development/debugging purposes. Isn't really applicable @@ -509,24 +509,24 @@ public: void SetENB(BOOL ast); // Set ENB signal - bool GetBSY(); + bool GetBSY() override; // Get BSY signal - void SetBSY(bool ast); + void SetBSY(bool ast) override; // Set BSY signal - BOOL GetSEL(); + BOOL GetSEL() override; // Get SEL signal - void SetSEL(BOOL ast); + void SetSEL(BOOL ast) override; // Set SEL signal - BOOL GetATN(); + BOOL GetATN() override; // Get ATN signal - void SetATN(BOOL ast); + void SetATN(BOOL ast) override; // Set ATN signal - BOOL GetACK(); + BOOL GetACK() override; // Get ACK signal - void SetACK(BOOL ast); + void SetACK(BOOL ast) override; // Set ACK signal BOOL GetACT(); @@ -534,42 +534,42 @@ public: void SetACT(BOOL ast); // Set ACT signal - BOOL GetRST(); + BOOL GetRST() override; // Get RST signal - void SetRST(BOOL ast); + void SetRST(BOOL ast) override; // Set RST signal - BOOL GetMSG(); + BOOL GetMSG() override; // Get MSG signal - void SetMSG(BOOL ast); + void SetMSG(BOOL ast) override; // Set MSG signal - BOOL GetCD(); + BOOL GetCD() override; // Get CD signal - void SetCD(BOOL ast); + void SetCD(BOOL ast) override; // Set CD signal - BOOL GetIO(); + BOOL GetIO() override; // Get IO signal - void SetIO(BOOL ast); + void SetIO(BOOL ast) override; // Set IO signal - BOOL GetREQ(); + BOOL GetREQ() override; // Get REQ signal - void SetREQ(BOOL ast); + void SetREQ(BOOL ast) override; // Set REQ signal - BYTE GetDAT(); + BYTE GetDAT() override; // Get DAT signal - void SetDAT(BYTE dat); + void SetDAT(BYTE dat) override; // Set DAT signal - BOOL GetDP(); + BOOL GetDP() override; // Get Data parity signal - int CommandHandShake(BYTE *buf); + int CommandHandShake(BYTE *buf) override; // Command receive handshake - int ReceiveHandShake(BYTE *buf, int count); + int ReceiveHandShake(BYTE *buf, int count) override; // Data receive handshake - int SendHandShake(BYTE *buf, int count, int delay_after_bytes); + int SendHandShake(BYTE *buf, int count, int delay_after_bytes) override; // Data transmission handshake static BUS::phase_t GetPhaseRaw(DWORD raw_data); diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index 84d30cfa..fa85c5f1 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -772,8 +772,9 @@ bool Insert(const CommandContext& context, const PbDeviceDefinition& pb_device, LOGINFO("Insert %sfile '%s' requested into %s ID %d, unit %d", pb_device.protected_() ? "protected " : "", filename.c_str(), device->GetType().c_str(), pb_device.id(), pb_device.unit()); + Disk *disk = dynamic_cast(device); + if (pb_device.block_size()) { - Disk *disk = dynamic_cast(device); if (disk && disk->IsSectorSizeConfigurable()) { if (!disk->SetConfiguredSectorSize(pb_device.block_size())) { return ReturnLocalizedError(context, ERROR_BLOCK_SIZE, to_string(pb_device.block_size())); @@ -822,7 +823,6 @@ bool Insert(const CommandContext& context, const PbDeviceDefinition& pb_device, device->SetProtected(pb_device.protected_()); } - Disk *disk = dynamic_cast(device); if (disk) { disk->MediumChanged(); } diff --git a/src/raspberrypi/scsi.h b/src/raspberrypi/scsi.h index b648390c..0c9ec109 100644 --- a/src/raspberrypi/scsi.h +++ b/src/raspberrypi/scsi.h @@ -148,6 +148,7 @@ public: virtual void SetDAT(BYTE dat) = 0; virtual BOOL GetDP() = 0; // Get parity signal + virtual DWORD Aquire() = 0; virtual int CommandHandShake(BYTE *buf) = 0; virtual int ReceiveHandShake(BYTE *buf, int count) = 0; virtual int SendHandShake(BYTE *buf, int count, int delay_after_bytes) = 0;