From 9099d7249cfaa32f46291e4f42ce05061ef1c760 Mon Sep 17 00:00:00 2001 From: Uwe Seimet <48174652+uweseimet@users.noreply.github.com> Date: Sun, 6 Mar 2022 16:17:23 +0100 Subject: [PATCH] SASI FORMAT opcode fix, SASI segfault fix, added SASI INQUIRY/READ CAPACITY, 512 bytes per sector SASI drives (#724) * Fixed opcode * Fixed segfault * Re-added 0x06 as additional SASI FORMAT opcode * Added support of SASI drives with 512 bytes * SASI LUN must always be taken from CDB and must be 0 or 1 * Fixed typo * Fixed one more SASI segfault * Removed duplicate code * Updated error handling * Updated error handling * Logging update * Added enum value for SPC-6 * Comment update * Added support for SASI Inquiry * Updated SASI LUN check * Updated SASI LUN handling * Comment update * Revert "Comment update" This reverts commit c6adbde25c29a68dc0574686b53b13b4dbf56207. * Updated logging * Implemented SASI READ CAPACITY * Validate SASI block count * Do not support ICD semantics for SASI drives * SASI READ CAPACITY is a group 1 command with 10 bytes * Comment update --- src/raspberrypi/controllers/sasidev_ctrl.cpp | 288 ++++--------------- src/raspberrypi/controllers/sasidev_ctrl.h | 18 +- src/raspberrypi/controllers/scsidev_ctrl.cpp | 7 +- src/raspberrypi/controllers/scsidev_ctrl.h | 3 + src/raspberrypi/devices/device_factory.cpp | 2 +- src/raspberrypi/devices/disk.h | 4 +- src/raspberrypi/devices/primary_device.cpp | 4 +- src/raspberrypi/devices/primary_device.h | 2 +- src/raspberrypi/devices/sasihd.cpp | 34 ++- src/raspberrypi/devices/sasihd.h | 1 + src/raspberrypi/gpiobus.cpp | 6 +- src/raspberrypi/gpiobus.h | 2 +- src/raspberrypi/scsi.h | 5 +- 13 files changed, 111 insertions(+), 265 deletions(-) diff --git a/src/raspberrypi/controllers/sasidev_ctrl.cpp b/src/raspberrypi/controllers/sasidev_ctrl.cpp index ef1a8ebb..80dd2b64 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.cpp +++ b/src/raspberrypi/controllers/sasidev_ctrl.cpp @@ -309,7 +309,7 @@ void SASIDEV::Command() ctrl.blocks = 1; // If no byte can be received move to the status phase - int count = ctrl.bus->CommandHandShake(ctrl.buffer); + int count = ctrl.bus->CommandHandShake(ctrl.buffer, IsSASI()); if (!count) { Error(); return; @@ -355,74 +355,95 @@ void SASIDEV::Execute() ctrl.blocks = 1; ctrl.execstart = SysTimer::GetTimerLow(); + int lun = GetEffectiveLun(); + if (!ctrl.unit[lun]) { + ctrl.device->SetStatusCode(STATUS_INVALIDLUN); + Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_LUN); + return; + } + + ctrl.device = ctrl.unit[lun]; + ctrl.device->SetCtrl(&ctrl); + // Discard pending sense data from the previous command if the current command is not REQUEST SENSE if ((SASIDEV::sasi_command)ctrl.cmd[0] != SASIDEV::eCmdRequestSense) { ctrl.status = 0; - ctrl.device->SetStatusCode(0); } // Process by command - // TODO This code does not belong here. Each device type needs such a dispatcher, which the controller has to call. switch ((SASIDEV::sasi_command)ctrl.cmd[0]) { - // TEST UNIT READY case SASIDEV::eCmdTestUnitReady: - CmdTestUnitReady(); + LOGTRACE( "%s TEST UNIT READY Command", __PRETTY_FUNCTION__); + ctrl.device->TestUnitReady(this); return; - // REZERO UNIT case SASIDEV::eCmdRezero: - CmdRezero(); + LOGTRACE( "%s REZERO Command", __PRETTY_FUNCTION__); + ((Disk *)ctrl.device)->Rezero(this); return; - // REQUEST SENSE case SASIDEV::eCmdRequestSense: - CmdRequestSense(); + LOGTRACE( "%s REQUEST SENSE Command", __PRETTY_FUNCTION__); + ctrl.device->RequestSense(this); return; - // FORMAT + // FORMAT (the old RaSCSI code used 0x06 as opcode, which is not compliant with the SASI specification) + // The FORMAT command of RaSCSI does not do anything but just returns a GOOD status case SASIDEV::eCmdFormat: - CmdFormat(); + case SASIDEV::eCmdFormatLegacy: + LOGTRACE( "%s FORMAT UNIT Command", __PRETTY_FUNCTION__); + ((Disk *)ctrl.device)->FormatUnit(this); + return; + + case SASIDEV::eCmdReadCapacity: + LOGTRACE( "%s READ CAPACITY Command", __PRETTY_FUNCTION__); + ((Disk *)ctrl.device)->ReadCapacity10(this); return; - // REASSIGN BLOCKS case SASIDEV::eCmdReassign: - CmdReassignBlocks(); + LOGTRACE( "%s REASSIGN BLOCKS Command", __PRETTY_FUNCTION__); + ((Disk *)ctrl.device)->ReassignBlocks(this); return; - // READ(6) case SASIDEV::eCmdRead6: - CmdRead6(); + LOGTRACE( "%s READ Command", __PRETTY_FUNCTION__); + ((Disk *)ctrl.device)->Read6(this); return; - // WRITE(6) case SASIDEV::eCmdWrite6: - CmdWrite6(); + LOGTRACE( "%s WRITE Command", __PRETTY_FUNCTION__); + ((Disk *)ctrl.device)->Write6(this); return; - // SEEK(6) case SASIDEV::eCmdSeek6: - CmdSeek6(); + LOGTRACE( "%s SEEK Command", __PRETTY_FUNCTION__); + ((Disk *)ctrl.device)->Seek(this); + return; + + case SASIDEV::eCmdInquiry: + LOGTRACE( "%s INQUIRY Command", __PRETTY_FUNCTION__); + ((Disk *)ctrl.device)->Inquiry(this); return; // ASSIGN (SASI only) - // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. + // This doesn't exist in the SASI Spec, but was in the original RaSCSI code. // leaving it here for now.... case SASIDEV::eCmdSasiCmdAssign: CmdAssign(); return; - // RESERVE UNIT(16) case SASIDEV::eCmdReserve6: - CmdReserveUnit(); + LOGTRACE( "%s RESERVE Command", __PRETTY_FUNCTION__); + ((Disk *)ctrl.device)->Reserve(this); return; - // RELEASE UNIT(17) case eCmdRelease6: - CmdReleaseUnit(); + LOGTRACE( "%s RELEASE Command", __PRETTY_FUNCTION__); + ((Disk *)ctrl.device)->Release(this); return; // SPECIFY (SASI only) - // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. + // This doesn't exist in the SASI Spec, but was in the original RaSCSI code. // leaving it here for now.... case SASIDEV::eCmdInvalid: CmdSpecify(); @@ -432,18 +453,11 @@ void SASIDEV::Execute() break; } - // Unsupported command LOGTRACE("%s ID %d received unsupported command: $%02X", __PRETTY_FUNCTION__, GetSCSIID(), (BYTE)ctrl.cmd[0]); - // Logical Unit - DWORD lun = GetEffectiveLun(); - if (ctrl.unit[lun]) { - // Command processing on drive - ctrl.unit[lun]->SetStatusCode(STATUS_INVALIDCMD); - } + ctrl.device->SetStatusCode(STATUS_INVALIDCMD); - // Failure (Error) - Error(); + Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE); } //--------------------------------------------------------------------------- @@ -618,11 +632,6 @@ void SASIDEV::DataOut() Receive(); } -//--------------------------------------------------------------------------- -// -// Error -// -//--------------------------------------------------------------------------- void SASIDEV::Error(sense_key sense_key, asc asc, status status) { // Get bus information @@ -644,205 +653,13 @@ void SASIDEV::Error(sense_key sense_key, asc asc, status status) return; } - // Logical Unit - DWORD lun = GetEffectiveLun(); - // Set status and message - ctrl.status = (lun << 5) | status; + ctrl.status = (GetEffectiveLun() << 5) | status; // status phase Status(); } -//--------------------------------------------------------------------------- -// -// TEST UNIT READY -// -//--------------------------------------------------------------------------- -void SASIDEV::CmdTestUnitReady() -{ - LOGTRACE("%s TEST UNIT READY Command ", __PRETTY_FUNCTION__); - - // Command processing on drive - ctrl.device->TestUnitReady(this); -} - -//--------------------------------------------------------------------------- -// -// REZERO UNIT -// -//--------------------------------------------------------------------------- -void SASIDEV::CmdRezero() -{ - LOGTRACE( "%s REZERO UNIT Command ", __PRETTY_FUNCTION__); - - // Command processing on drive - ((Disk *)ctrl.device)->Rezero(this); -} - -//--------------------------------------------------------------------------- -// -// REQUEST SENSE -// -//--------------------------------------------------------------------------- -void SASIDEV::CmdRequestSense() -{ - LOGTRACE( "%s REQUEST SENSE Command ", __PRETTY_FUNCTION__); - - // Command processing on drive - ctrl.device->RequestSense(this); -} - -//--------------------------------------------------------------------------- -// -// FORMAT UNIT -// -//--------------------------------------------------------------------------- -void SASIDEV::CmdFormat() -{ - LOGTRACE( "%s FORMAT UNIT Command ", __PRETTY_FUNCTION__); - - // Command processing on drive - ((Disk *)ctrl.device)->FormatUnit(this); -} - -//--------------------------------------------------------------------------- -// -// REASSIGN BLOCKS -// -//--------------------------------------------------------------------------- -void SASIDEV::CmdReassignBlocks() -{ - LOGTRACE("%s REASSIGN BLOCKS Command ", __PRETTY_FUNCTION__); - - // Command processing on drive - ((Disk *)ctrl.device)->ReassignBlocks(this); -} - -//--------------------------------------------------------------------------- -// -// RESERVE UNIT(16) -// -// 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 SASIDEV::CmdReserveUnit() -{ - LOGTRACE( "%s Reserve(6) Command", __PRETTY_FUNCTION__); - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// RELEASE UNIT(17) -// -// 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 SASIDEV::CmdReleaseUnit() -{ - LOGTRACE( "%s Release(6) Command", __PRETTY_FUNCTION__); - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// READ(6) -// -//--------------------------------------------------------------------------- -void SASIDEV::CmdRead6() -{ - // Get record number and block number - DWORD record = ctrl.cmd[1] & 0x1f; - record <<= 8; - record |= ctrl.cmd[2]; - record <<= 8; - record |= ctrl.cmd[3]; - ctrl.blocks = ctrl.cmd[4]; - if (ctrl.blocks == 0) { - ctrl.blocks = 0x100; - } - - LOGTRACE("%s READ(6) command record=%d blocks=%d", __PRETTY_FUNCTION__, (unsigned int)record, (int)ctrl.blocks); - - // Command processing on drive - ctrl.length = ((Disk *)ctrl.device)->Read(ctrl.cmd, ctrl.buffer, record); - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Set next block - ctrl.next = record + 1; - - // Read phase - DataIn(); -} - -//--------------------------------------------------------------------------- -// -// WRITE(6) -// -//--------------------------------------------------------------------------- -void SASIDEV::CmdWrite6() -{ - // Get record number and block number - DWORD record = ctrl.cmd[1] & 0x1f; - record <<= 8; - record |= ctrl.cmd[2]; - record <<= 8; - record |= ctrl.cmd[3]; - ctrl.blocks = ctrl.cmd[4]; - if (ctrl.blocks == 0) { - ctrl.blocks = 0x100; - } - - LOGTRACE("%s WRITE(6) command record=%d blocks=%d", __PRETTY_FUNCTION__, (WORD)record, (WORD)ctrl.blocks); - - // Command processing on drive - ctrl.length = ((Disk *)ctrl.device)->WriteCheck(record); - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Set next block - ctrl.next = record + 1; - - // Write phase - DataOut(); -} - -//--------------------------------------------------------------------------- -// -// SEEK(6) -// -//--------------------------------------------------------------------------- -void SASIDEV::CmdSeek6() -{ - LOGTRACE("%s SEEK(6) Command ", __PRETTY_FUNCTION__); - - // Command processing on drive - ((Disk *)ctrl.device)->Seek6(this); -} - -//--------------------------------------------------------------------------- -// -// ASSIGN -// -//--------------------------------------------------------------------------- void SASIDEV::CmdAssign() { LOGTRACE("%s ASSIGN Command ", __PRETTY_FUNCTION__); @@ -862,11 +679,6 @@ void SASIDEV::CmdAssign() DataOut(); } -//--------------------------------------------------------------------------- -// -// SPECIFY -// -//--------------------------------------------------------------------------- void SASIDEV::CmdSpecify() { LOGTRACE("%s SPECIFY Command ", __PRETTY_FUNCTION__); @@ -1276,6 +1088,6 @@ void SASIDEV::FlushUnit() int SASIDEV::GetEffectiveLun() const { - return ctrl.lun != -1 ? ctrl.lun : (ctrl.cmd[1] >> 5) & 0x07; + return (ctrl.cmd[1] >> 5) & 0x07; } diff --git a/src/raspberrypi/controllers/sasidev_ctrl.h b/src/raspberrypi/controllers/sasidev_ctrl.h index b59d1828..5917cf39 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.h +++ b/src/raspberrypi/controllers/sasidev_ctrl.h @@ -36,12 +36,15 @@ private: eCmdTestUnitReady = 0x00, eCmdRezero = 0x01, eCmdRequestSense = 0x03, - eCmdFormat = 0x06, + eCmdFormat = 0x04, + eCmdReadCapacity = 0x05, + eCmdFormatLegacy = 0x06, eCmdReassign = 0x07, eCmdRead6 = 0x08, eCmdWrite6 = 0x0A, eCmdSeek6 = 0x0B, eCmdSetMcastAddr = 0x0D, // DaynaPort specific command + eCmdInquiry = 0x12, eCmdModeSelect6 = 0x15, eCmdReserve6 = 0x16, eCmdRelease6 = 0x17, @@ -137,8 +140,7 @@ public: void MsgIn(); // Message in phase void DataOut(); // Data out phase - // Get LUN based on IDENTIFY message, with LUN from the CDB as fallback - int GetEffectiveLun() const; + virtual int GetEffectiveLun() const; virtual void Error(scsi_defs::sense_key sense_key = scsi_defs::sense_key::NO_SENSE, scsi_defs::asc = scsi_defs::asc::NO_ADDITIONAL_SENSE_INFORMATION, @@ -152,16 +154,6 @@ protected: virtual void Execute(); // Execution phase // Commands - void CmdTestUnitReady(); // TEST UNIT READY command - void CmdRezero(); // REZERO UNIT command - void CmdRequestSense(); // REQUEST SENSE command - void CmdFormat(); // FORMAT command - void CmdReassignBlocks(); // REASSIGN BLOCKS command - void CmdReserveUnit(); // RESERVE UNIT command - void CmdReleaseUnit(); // RELEASE UNIT command - void CmdRead6(); // READ(6) command - void CmdWrite6(); // WRITE(6) command - void CmdSeek6(); // SEEK(6) command void CmdAssign(); // ASSIGN command void CmdSpecify(); // SPECIFY command diff --git a/src/raspberrypi/controllers/scsidev_ctrl.cpp b/src/raspberrypi/controllers/scsidev_ctrl.cpp index 9e6c40e5..a6fcdd6e 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.cpp +++ b/src/raspberrypi/controllers/scsidev_ctrl.cpp @@ -274,7 +274,7 @@ void SCSIDEV::Execute() int lun = GetEffectiveLun(); if (!ctrl.unit[lun]) { - if ((scsi_command)ctrl.cmd[0] != eCmdInquiry && + if ((scsi_command)ctrl.cmd[0] != scsi_command::eCmdInquiry && (scsi_command)ctrl.cmd[0] != scsi_command::eCmdRequestSense) { LOGDEBUG("Invalid LUN %d for ID %d", lun, GetSCSIID()); @@ -911,3 +911,8 @@ bool SCSIDEV::XferOut(bool cont) return false; } +int SCSIDEV::GetEffectiveLun() const +{ + return ctrl.lun != -1 ? ctrl.lun : (ctrl.cmd[1] >> 5) & 0x07; +} + diff --git a/src/raspberrypi/controllers/scsidev_ctrl.h b/src/raspberrypi/controllers/scsidev_ctrl.h index 2a0660df..7d4fb0b0 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.h +++ b/src/raspberrypi/controllers/scsidev_ctrl.h @@ -62,6 +62,9 @@ public: void Receive() override; + // Get LUN based on IDENTIFY message, with LUN from the CDB as fallback + int GetEffectiveLun() const; + bool IsSASI() const override { return false; } bool IsSCSI() const override { return true; } diff --git a/src/raspberrypi/devices/device_factory.cpp b/src/raspberrypi/devices/device_factory.cpp index 731f675f..5fb7680b 100644 --- a/src/raspberrypi/devices/device_factory.cpp +++ b/src/raspberrypi/devices/device_factory.cpp @@ -25,7 +25,7 @@ using namespace rascsi_interface; DeviceFactory::DeviceFactory() { - sector_sizes[SAHD] = { 256, 1024 }; + sector_sizes[SAHD] = { 256, 512, 1024 }; sector_sizes[SCHD] = { 512, 1024, 2048, 4096 }; sector_sizes[SCRM] = { 512, 1024, 2048, 4096 }; sector_sizes[SCMO] = { 512, 1024, 2048, 4096 }; diff --git a/src/raspberrypi/devices/disk.h b/src/raspberrypi/devices/disk.h index 47109c5c..691ed5df 100644 --- a/src/raspberrypi/devices/disk.h +++ b/src/raspberrypi/devices/disk.h @@ -71,6 +71,8 @@ public: bool Eject(bool) override; private: + friend class SASIDEV; + typedef ModePageDevice super; // Commands covered by the SCSI specification (see https://www.t10.org/drafts.htm) @@ -94,7 +96,7 @@ private: void Verify16(SASIDEV *); void Seek(SASIDEV *); void Seek10(SASIDEV *); - void ReadCapacity10(SASIDEV *) override; + virtual void ReadCapacity10(SASIDEV *) override; void ReadCapacity16(SASIDEV *) override; void Reserve(SASIDEV *); void Release(SASIDEV *); diff --git a/src/raspberrypi/devices/primary_device.cpp b/src/raspberrypi/devices/primary_device.cpp index c1d6a6b5..7ecd96e2 100644 --- a/src/raspberrypi/devices/primary_device.cpp +++ b/src/raspberrypi/devices/primary_device.cpp @@ -128,8 +128,6 @@ void PrimaryDevice::RequestSense(SASIDEV *controller) memcpy(ctrl->buffer, buf.data(), allocation_length); ctrl->length = allocation_length; - LOGTRACE("%s Status $%02X, Sense Key $%02X, ASC $%02X",__PRETTY_FUNCTION__, ctrl->status, ctrl->buffer[2], ctrl->buffer[12]); - controller->DataIn(); } @@ -205,6 +203,8 @@ vector PrimaryDevice::RequestSense(int) buf[12] = GetStatusCode() >> 8; buf[13] = GetStatusCode(); + LOGTRACE("%s Status $%02X, Sense Key $%02X, ASC $%02X",__PRETTY_FUNCTION__, ctrl->status, ctrl->buffer[2], ctrl->buffer[12]); + return buf; } diff --git a/src/raspberrypi/devices/primary_device.h b/src/raspberrypi/devices/primary_device.h index 4ba6661a..bce506c3 100644 --- a/src/raspberrypi/devices/primary_device.h +++ b/src/raspberrypi/devices/primary_device.h @@ -30,6 +30,7 @@ public: void TestUnitReady(SASIDEV *); void RequestSense(SASIDEV *); + virtual void Inquiry(SASIDEV *); void SetCtrl(SASIDEV::ctrl_t *ctrl) { this->ctrl = ctrl; } @@ -49,6 +50,5 @@ private: Dispatcher dispatcher; - void Inquiry(SASIDEV *); void ReportLuns(SASIDEV *); }; diff --git a/src/raspberrypi/devices/sasihd.cpp b/src/raspberrypi/devices/sasihd.cpp index 9d356f2b..9f36d118 100644 --- a/src/raspberrypi/devices/sasihd.cpp +++ b/src/raspberrypi/devices/sasihd.cpp @@ -53,6 +53,11 @@ void SASIHD::Open(const Filepath& path) SetSectorSizeInBytes(GetConfiguredSectorSize() ? GetConfiguredSectorSize() : 256, true); SetBlockCount((DWORD)(size >> GetSectorSizeShiftCount())); + // SASI only supports READ/WRITE(6), limiting the block count to 2^21 + if (GetBlockCount() > 2097152) { + throw io_exception("SASI drives are limited to 2097152 blocks"); + } + #if defined(REMOVE_FIXED_SASIHD_SIZE) // Effective size must be a multiple of the sector size size = (size / GetSectorSizeInBytes()) * GetSectorSizeInBytes(); @@ -83,8 +88,9 @@ void SASIHD::Open(const Filepath& path) vector SASIHD::Inquiry() const { - assert(false); - return vector(0); + // Byte 0 = 0: Direct access device + + return vector(2); } vector SASIHD::RequestSense(int allocation_length) @@ -96,5 +102,29 @@ vector SASIHD::RequestSense(int allocation_length) buf[0] = (BYTE)(GetStatusCode() >> 16); buf[1] = (BYTE)(GetLun() << 5); + LOGTRACE("%s Status $%02X",__PRETTY_FUNCTION__, buf[0]); + return buf; } + +void SASIHD::ReadCapacity10(SASIDEV *controller) +{ + BYTE *buf = ctrl->buffer; + + // Create end of logical block address (disk.blocks-1) + uint32_t blocks = disk.blocks - 1; + buf[0] = (BYTE)(blocks >> 24); + buf[1] = (BYTE)(blocks >> 16); + buf[2] = (BYTE)(blocks >> 8); + buf[3] = (BYTE)blocks; + + // Create block length (1 << disk.size) + uint32_t length = 1 << disk.size; + buf[4] = (BYTE)(length >> 8); + buf[5] = (BYTE)length; + + // the size + ctrl->length = 6; + + controller->DataIn(); +} diff --git a/src/raspberrypi/devices/sasihd.h b/src/raspberrypi/devices/sasihd.h index 489139da..df0aa1e9 100644 --- a/src/raspberrypi/devices/sasihd.h +++ b/src/raspberrypi/devices/sasihd.h @@ -35,4 +35,5 @@ public: vector RequestSense(int) override; vector Inquiry() const override; + virtual void ReadCapacity10(SASIDEV *) override; }; diff --git a/src/raspberrypi/gpiobus.cpp b/src/raspberrypi/gpiobus.cpp index 6d0b155d..e12c4935 100644 --- a/src/raspberrypi/gpiobus.cpp +++ b/src/raspberrypi/gpiobus.cpp @@ -817,7 +817,7 @@ BOOL GPIOBUS::GetDP() // Receive command handshake // //--------------------------------------------------------------------------- -int GPIOBUS::CommandHandShake(BYTE *buf) +int GPIOBUS::CommandHandShake(BYTE *buf, bool is_sasi) { int count; @@ -869,7 +869,7 @@ int GPIOBUS::CommandHandShake(BYTE *buf) // semantics. I fact, these semantics have become a standard in the Atari world. // RaSCSI becomes ICD compatible by ignoring the prepended $1F byte before processing the CDB. - if (*buf == 0x1F) { + if (!is_sasi && *buf == 0x1F) { SetSignal(PIN_REQ, ON); ret = WaitSignal(PIN_ACK, TRUE); @@ -1592,7 +1592,7 @@ int GPIOBUS::GetCommandByteCount(BYTE opcode) { else if (opcode == 0xA0) { return 12; } - else if (opcode >= 0x20 && opcode <= 0x7D) { + else if (opcode == 0x05 || (opcode >= 0x20 && opcode <= 0x7D)) { return 10; } else { return 6; diff --git a/src/raspberrypi/gpiobus.h b/src/raspberrypi/gpiobus.h index 622cc493..2154ad8e 100644 --- a/src/raspberrypi/gpiobus.h +++ b/src/raspberrypi/gpiobus.h @@ -565,7 +565,7 @@ public: // Set DAT signal BOOL GetDP() override; // Get Data parity signal - int CommandHandShake(BYTE *buf) override; + int CommandHandShake(BYTE *buf, bool) override; // Command receive handshake int ReceiveHandShake(BYTE *buf, int count) override; // Data receive handshake diff --git a/src/raspberrypi/scsi.h b/src/raspberrypi/scsi.h index f8cb6f80..2f746f7b 100644 --- a/src/raspberrypi/scsi.h +++ b/src/raspberrypi/scsi.h @@ -98,7 +98,7 @@ public: virtual BOOL GetDP() = 0; // Get parity signal virtual DWORD Aquire() = 0; - virtual int CommandHandShake(BYTE *buf) = 0; + virtual int CommandHandShake(BYTE *buf, bool) = 0; virtual int ReceiveHandShake(BYTE *buf, int count) = 0; virtual int SendHandShake(BYTE *buf, int count, int delay_after_bytes) = 0; @@ -131,7 +131,8 @@ namespace scsi_defs { SPC_2 = 4, SPC_3 = 5, SPC_4 = 6, - SPC_5 = 7 + SPC_5 = 7, + SPC_6 = 8 }; enum device_type : int {