Disk ID handling improvements (#149)

* Replaced DWORD ID by string

* Signature update

* Removed unused code

* Added getters for all device types

* Renaming

* Removed unused code

* Renaming

* Updated more ID checks

* Removed unused code

* Use IsSCSI()
This commit is contained in:
Uwe Seimet 2021-07-24 02:41:55 +02:00 committed by GitHub
parent 55ec2291ef
commit b3862c4726
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 90 additions and 124 deletions

View File

@ -904,20 +904,20 @@ void FASTCALL SASIDEV::CmdRead6()
ctrl.blocks = 0x100;
}
if(ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'D', 'P')){
if(ctrl.unit[lun]->IsDaynaPort()){
// The DaynaPort only wants one block.
// ctrl.cmd[4] and ctrl.cmd[5] are used to specify the maximum buffer size for the DaynaPort
ctrl.blocks=1;
}
LOGTRACE("%s READ(6) command record=%06X blocks=%d ID %08X", __PRETTY_FUNCTION__, (unsigned int)record, (int)ctrl.blocks, (unsigned int)ctrl.unit[lun]->GetID());
LOGTRACE("%s READ(6) command record=%06X blocks=%d ID %s", __PRETTY_FUNCTION__, (unsigned int)record, (int)ctrl.blocks, ctrl.unit[lun]->GetID().c_str());
// Command processing on drive
ctrl.length = ctrl.unit[lun]->Read(ctrl.cmd, ctrl.buffer, record);
LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, (int)ctrl.length);
// The DaynaPort will respond a status of 0x02 when a read of size 1 occurs.
if ((ctrl.length <= 0) && (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P'))) {
if (ctrl.length <= 0 && !ctrl.unit[lun]->IsDaynaPort()) {
// Failure (Error)
Error();
return;
@ -940,7 +940,7 @@ void FASTCALL SASIDEV::DaynaPortWrite()
DWORD lun = GetLun();
// Error if not a host bridge
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')) {
if (!ctrl.unit[lun]->IsDaynaPort()) {
LOGERROR("Received DaynaPortWrite for a non-DaynaPort device");
Error();
return;
@ -989,10 +989,10 @@ void FASTCALL SASIDEV::DaynaPortWrite()
//---------------------------------------------------------------------------
void FASTCALL SASIDEV::CmdWrite6()
{
DWORD lun = GetLun();
DWORD lun = GetLun();
// Special receive function for the DaynaPort
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'D', 'P')){
if (ctrl.unit[lun]->IsDaynaPort()){
DaynaPortWrite();
return;
}
@ -1375,7 +1375,7 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
case SASIDEV::eCmdWriteAndVerify10:
// If we're a host bridge, use the host bridge's SendMessage10
// function
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) {
if (ctrl.unit[lun]->IsBridge()) {
bridge = (SCSIBR*)ctrl.unit[lun];
if (!bridge->SendMessage10(ctrl.cmd, ctrl.buffer)) {
// write failed
@ -1388,7 +1388,7 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont)
}
// Special case Write function for DaynaPort
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'D', 'P')) {
if (ctrl.unit[lun]->IsDaynaPort()) {
LOGTRACE("%s Doing special case write for DaynaPort", __PRETTY_FUNCTION__);
if (!(SCSIDaynaPort*)ctrl.unit[lun]->Write(ctrl.cmd, ctrl.buffer, ctrl.length)) {
// write failed

View File

@ -679,7 +679,7 @@ void FASTCALL SCSIDEV::CmdRead10()
DWORD lun = GetLun();
// Receive message if host bridge
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) {
if (ctrl.unit[lun]->IsBridge()) {
CmdGetMessage10();
return;
}
@ -729,7 +729,7 @@ void FASTCALL SCSIDEV::CmdWrite10()
DWORD lun = GetLun();
// Receive message with host bridge
if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) {
if (ctrl.unit[lun]->IsBridge()) {
CmdSendMessage10();
return;
}
@ -1037,8 +1037,7 @@ void FASTCALL SCSIDEV::CmdGetMessage10()
DWORD lun = GetLun();
// Error if not a host bridge
if ((ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) &&
(ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'N', 'L'))){
if (!ctrl.unit[lun]->IsBridge() && !ctrl.unit[lun]->IsNuvolink()) {
LOGWARN("Received a GetMessage10 command for a non-bridge unit");
Error();
return;
@ -1081,7 +1080,7 @@ void FASTCALL SCSIDEV::CmdSendMessage10()
DWORD lun = GetLun();
// Error if not a host bridge
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) {
if (!ctrl.unit[lun]->IsBridge()) {
LOGERROR("Received CmdSendMessage10 for a non-bridge device");
Error();
return;
@ -1125,8 +1124,8 @@ void FASTCALL SCSIDEV::CmdRetrieveStats()
DWORD lun = GetLun();
// Error if not a DaynaPort SCSI Link
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){
LOGWARN("Received a CmdRetrieveStats command for a non-daynaport unit %08X", (unsigned int)ctrl.unit[lun]->GetID());
if (ctrl.unit[lun]->IsDaynaPort()) {
LOGWARN("Received a CmdRetrieveStats command for a non-daynaport unit %s", ctrl.unit[lun]->GetID().c_str());
Error();
return;
}
@ -1161,8 +1160,8 @@ void FASTCALL SCSIDEV::CmdSetIfaceMode()
DWORD lun = GetLun();
// Error if not a DaynaPort SCSI Link
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){
LOGWARN("%s Received a CmdRetrieveStats command for a non-daynaport unit %08X", __PRETTY_FUNCTION__, (unsigned int)ctrl.unit[lun]->GetID());
if (!ctrl.unit[lun]->IsDaynaPort()) {
LOGWARN("%s Received a CmdRetrieveStats command for a non-daynaport unit %s", __PRETTY_FUNCTION__, ctrl.unit[lun]->GetID().c_str());
Error();
return;
}
@ -1200,7 +1199,7 @@ void FASTCALL SCSIDEV::CmdSetMcastAddr()
DWORD lun = GetLun();
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){
if (!ctrl.unit[lun]->IsDaynaPort()) {
LOGWARN("Received a SetMcastAddress command for a non-daynaport unit");
Error();
return;
@ -1233,8 +1232,8 @@ void FASTCALL SCSIDEV::CmdEnableInterface()
DWORD lun = GetLun();
// Error if not a DaynaPort SCSI Link
if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){
LOGWARN("%s Received a CmdRetrieveStats command for a non-daynaport unit %08X", __PRETTY_FUNCTION__, (unsigned int)ctrl.unit[lun]->GetID());
if (!ctrl.unit[lun]->IsDaynaPort()) {
LOGWARN("%s Received a CmdRetrieveStats command for a non-daynaport unit %s", __PRETTY_FUNCTION__, ctrl.unit[lun]->GetID().c_str());
Error();
return;
}
@ -1280,7 +1279,7 @@ void FASTCALL SCSIDEV::Send()
// 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.
if (ctrl.unit[0] && ctrl.unit[0]->GetID() == MAKEID('S', 'C', 'D', 'P')) {
if (ctrl.unit[0] && ctrl.unit[0]->IsDaynaPort()) {
len = ((GPIOBUS*)ctrl.bus)->SendHandShake(
&ctrl.buffer[ctrl.offset], ctrl.length, SCSIDaynaPort::DAYNAPORT_READ_HEADER_SZ);
}

View File

@ -706,7 +706,6 @@ void FASTCALL DiskCache::Update()
Disk::Disk()
{
// Work initialization
disk.id = MAKEID('N', 'U', 'L', 'L');
disk.ready = FALSE;
disk.writep = FALSE;
disk.readonly = FALSE;
@ -765,12 +764,9 @@ void FASTCALL Disk::Reset()
// NULL Check
//
//---------------------------------------------------------------------------
BOOL FASTCALL Disk::IsNULL() const
bool FASTCALL Disk::IsNULL() const
{
if (disk.id == MAKEID('N', 'U', 'L', 'L')) {
return TRUE;
}
return FALSE;
return disk.id.empty();
}
//---------------------------------------------------------------------------
@ -778,7 +774,7 @@ BOOL FASTCALL Disk::IsNULL() const
// Retrieve the disk's ID
//
//---------------------------------------------------------------------------
DWORD FASTCALL Disk::GetID() const
const std::string& FASTCALL Disk::GetID() const
{
return disk.id;
}
@ -789,7 +785,7 @@ DWORD FASTCALL Disk::GetID() const
// Get cache writeback mode
//
//---------------------------------------------------------------------------
BOOL FASTCALL Disk::IsCacheWB()
bool FASTCALL Disk::IsCacheWB()
{
return cache_wb;
}
@ -806,36 +802,43 @@ void FASTCALL Disk::SetCacheWB(BOOL enable)
//---------------------------------------------------------------------------
//
// Set unsupported command
// Device type checks
//
//---------------------------------------------------------------------------
void FASTCALL Disk::InvalidCmd()
{
disk.code = DISK_INVALIDCMD;
bool FASTCALL Disk::IsSASI() const
{
return disk.id == "SAHD";
}
//---------------------------------------------------------------------------
//
// SASI Check
//
//---------------------------------------------------------------------------
BOOL FASTCALL Disk::IsSASI() const
bool FASTCALL Disk::IsSCSI() const
{
if (disk.id == MAKEID('S', 'A', 'H', 'D')) {
return TRUE;
}
return FALSE;
return disk.id == "SCHD";
}
//---------------------------------------------------------------------------
//
// SCSI Check
//
//---------------------------------------------------------------------------
BOOL FASTCALL Disk::IsSCSI() const
bool FASTCALL Disk::IsCdRom() const
{
// If this isn't SASI, then it must be SCSI.
return (this->IsSASI()) ? FALSE : TRUE;
return disk.id == "SCCD";
}
bool FASTCALL Disk::IsMo() const
{
return disk.id == "SCMO";
}
bool FASTCALL Disk::IsBridge() const
{
return disk.id == "SCBR";
}
bool FASTCALL Disk::IsDaynaPort() const
{
return disk.id == "SCDP";
}
bool FASTCALL Disk::IsNuvolink() const
{
return disk.id == "SCNL";
}
//---------------------------------------------------------------------------
@ -938,19 +941,6 @@ void FASTCALL Disk::WriteP(BOOL writep)
disk.writep = writep;
}
//---------------------------------------------------------------------------
//
// Get Disk
//
//---------------------------------------------------------------------------
void FASTCALL Disk::GetDisk(disk_t *buffer) const
{
ASSERT(buffer);
// Assign internal buffer
*buffer = disk;
}
//---------------------------------------------------------------------------
//
// Get Path
@ -1087,7 +1077,7 @@ int FASTCALL Disk::SelectCheck(const DWORD *cdb)
ASSERT(cdb);
// Error if save parameters are set instead of SCSIHD
if (disk.id != MAKEID('S', 'C', 'H', 'D')) {
if (!IsSCSI()) {
// Error if save parameters are set
if (cdb[1] & 0x01) {
disk.code = DISK_INVALIDCDB;
@ -1112,7 +1102,7 @@ int FASTCALL Disk::SelectCheck10(const DWORD *cdb)
ASSERT(cdb);
// Error if save parameters are set instead of SCSIHD
if (disk.id != MAKEID('S', 'C', 'H', 'D')) {
if (!IsSCSI()) {
if (cdb[1] & 0x01) {
disk.code = DISK_INVALIDCDB;
return 0;
@ -1188,7 +1178,7 @@ int FASTCALL Disk::ModeSense(const DWORD *cdb, BYTE *buf)
int size = 4;
// MEDIUM TYPE
if (disk.id == MAKEID('S', 'C', 'M', 'O')) {
if (IsMo()) {
buf[1] = 0x03; // optical reversible or erasable
}
@ -1239,7 +1229,7 @@ int FASTCALL Disk::ModeSense(const DWORD *cdb, BYTE *buf)
}
// Page code 6(optical)
if (disk.id == MAKEID('S', 'C', 'M', 'O')) {
if (IsMo()) {
if ((page == 0x06) || (page == 0x3f)) {
size += AddOpt(change, &buf[size]);
valid = TRUE;
@ -1253,7 +1243,7 @@ int FASTCALL Disk::ModeSense(const DWORD *cdb, BYTE *buf)
}
// Page code 13(CD-ROM)
if (disk.id == MAKEID('S', 'C', 'C', 'D')) {
if (IsCdRom()) {
if ((page == 0x0d) || (page == 0x3f)) {
size += AddCDROM(change, &buf[size]);
valid = TRUE;
@ -1261,7 +1251,7 @@ int FASTCALL Disk::ModeSense(const DWORD *cdb, BYTE *buf)
}
// Page code 14(CD-DA)
if (disk.id == MAKEID('S', 'C', 'C', 'D')) {
if (IsCdRom()) {
if ((page == 0x0e) || (page == 0x3f)) {
size += AddCDDA(change, &buf[size]);
valid = TRUE;
@ -1378,7 +1368,7 @@ int FASTCALL Disk::ModeSense10(const DWORD *cdb, BYTE *buf)
}
// ペPage code 6(optical)
if (disk.id == MAKEID('S', 'C', 'M', 'O')) {
if (IsMo()) {
if ((page == 0x06) || (page == 0x3f)) {
size += AddOpt(change, &buf[size]);
valid = TRUE;
@ -1392,7 +1382,7 @@ int FASTCALL Disk::ModeSense10(const DWORD *cdb, BYTE *buf)
}
// Page code 13(CD-ROM)
if (disk.id == MAKEID('S', 'C', 'C', 'D')) {
if (IsCdRom()) {
if ((page == 0x0d) || (page == 0x3f)) {
size += AddCDROM(change, &buf[size]);
valid = TRUE;
@ -1400,7 +1390,7 @@ int FASTCALL Disk::ModeSense10(const DWORD *cdb, BYTE *buf)
}
// Page code 14(CD-DA)
if (disk.id == MAKEID('S', 'C', 'C', 'D')) {
if (IsCdRom()) {
if ((page == 0x0e) || (page == 0x3f)) {
size += AddCDDA(change, &buf[size]);
valid = TRUE;

View File

@ -164,7 +164,7 @@ class Disk
public:
// Internal data structure
typedef struct {
DWORD id; // Media ID
std::string id; // Media ID
BOOL ready; // Valid Disk
BOOL writep; // Write protected
BOOL readonly; // Read only
@ -187,10 +187,15 @@ public:
virtual void FASTCALL Reset(); // Device Reset
// ID
DWORD FASTCALL GetID() const; // Get media ID
BOOL FASTCALL IsNULL() const; // NULL check
BOOL FASTCALL IsSASI() const; // SASI Check
BOOL FASTCALL IsSCSI() const; // SASI Check
const std::string& FASTCALL GetID() const; // Get media ID
bool FASTCALL IsNULL() const; // NULL check
bool FASTCALL IsSASI() const; // SASI Check
bool FASTCALL IsSCSI() const; // SASI Check
bool FASTCALL IsCdRom() const;
bool FASTCALL IsMo() const;
bool FASTCALL IsBridge() const;
bool FASTCALL IsDaynaPort() const;
bool FASTCALL IsNuvolink() const;
// Media Operations
virtual BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); // Open
@ -204,7 +209,6 @@ public:
BOOL FASTCALL IsLocked() const { return disk.lock; } // Get locked status
BOOL FASTCALL IsAttn() const { return disk.attn; } // Get attention flag
BOOL FASTCALL Flush(); // Flush the cache
void FASTCALL GetDisk(disk_t *buffer) const; // Get the internal data struct
// Properties
void FASTCALL SetLUN(DWORD lun) { disk.lun = lun; } // LUN set
@ -238,10 +242,9 @@ public:
virtual BOOL FASTCALL PlayAudio(const DWORD *cdb); // PLAY AUDIO command
virtual BOOL FASTCALL PlayAudioMSF(const DWORD *cdb); // PLAY AUDIO MSF command
virtual BOOL FASTCALL PlayAudioTrack(const DWORD *cdb); // PLAY AUDIO TRACK command
void FASTCALL InvalidCmd(); // Unsupported command
// Other
BOOL FASTCALL IsCacheWB(); // Get cache writeback mode
bool FASTCALL IsCacheWB(); // Get cache writeback mode
void FASTCALL SetCacheWB(BOOL enable); // Set cache writeback mode
protected:

View File

@ -32,7 +32,7 @@
SASIHD::SASIHD() : Disk()
{
// SASI ハードディスク
disk.id = MAKEID('S', 'A', 'H', 'D');
disk.id = "SAHD";
}
//---------------------------------------------------------------------------

View File

@ -51,7 +51,7 @@ SCSIDaynaPort::SCSIDaynaPort() : Disk()
{
LOGTRACE("SCSI DaynaPort Constructor");
// DaynaPort
disk.id = MAKEID('S', 'C', 'D', 'P');
disk.id = "SCDP";
#ifdef __linux__
// TAP Driver Generation

View File

@ -40,7 +40,7 @@ SCSIBR::SCSIBR() : Disk()
packet_len = 0;
// Host Bridge
disk.id = MAKEID('S', 'C', 'B', 'R');
disk.id = "SCBR";
#ifdef __linux__
// TAP Driver Generation

View File

@ -254,7 +254,7 @@ SCSICD::SCSICD() : Disk()
int i;
// SCSI CD-ROM
disk.id = MAKEID('S', 'C', 'C', 'D');
disk.id = "SCCD";
// removable, write protected
disk.removable = TRUE;

View File

@ -31,7 +31,7 @@
SCSIHD::SCSIHD() : Disk()
{
// SCSI Hard Disk
disk.id = MAKEID('S', 'C', 'H', 'D');
disk.id = "SCHD";
}
//---------------------------------------------------------------------------

View File

@ -32,7 +32,7 @@
SCSIMO::SCSIMO() : Disk()
{
// SCSI magneto-optical disk
disk.id = MAKEID('S', 'C', 'M', 'O');
disk.id = "SCMO";
// Set as removable
disk.removable = TRUE;

View File

@ -274,18 +274,12 @@ PbDevices GetDevices() {
device->set_un(i % UnitNum);
// ID,UNIT,Type,Device Status
char type[5];
type[0] = (char)(pUnit->GetID() >> 24);
type[1] = (char)(pUnit->GetID() >> 16);
type[2] = (char)(pUnit->GetID() >> 8);
type[3] = (char)(pUnit->GetID());
type[4] = 0;
device->set_type(type);
device->set_type(pUnit->GetID());
// mount status output
if (pUnit->GetID() == MAKEID('S', 'C', 'B', 'R')) {
if (pUnit->IsBridge()) {
device->set_file("X68000 HOST BRIDGE");
} else if (pUnit->GetID() == MAKEID('S', 'C', 'D', 'P')) {
} else if (pUnit->IsDaynaPort()) {
device->set_file("DaynaPort SCSI/Link");
} else {
Filepath filepath;
@ -593,13 +587,7 @@ bool ProcessCmd(int fd, const PbCommand &command)
// Re-map the controller
bool status = MapController(map);
if (status) {
type_str[0] = (char)(pUnit->GetID() >> 24);
type_str[1] = (char)(pUnit->GetID() >> 16);
type_str[2] = (char)(pUnit->GetID() >> 8);
type_str[3] = (char)(pUnit->GetID());
type_str[4] = '\0';
LOGINFO("rasctl added new %s device. ID: %d UN: %d", type_str, id, un);
LOGINFO("rasctl added new %s device. ID: %d UN: %d", pUnit->GetID().c_str(), id, un);
}
return ReturnStatus(fd, status, status ? "" : "Error : SASI and SCSI can't be mixed\n");
@ -620,15 +608,9 @@ bool ProcessCmd(int fd, const PbCommand &command)
return ReturnStatus(fd, false, "Error : No such device");
}
type_str[0] = (char)(pUnit->GetID() >> 24);
type_str[1] = (char)(pUnit->GetID() >> 16);
type_str[2] = (char)(pUnit->GetID() >> 8);
type_str[3] = (char)(pUnit->GetID());
type_str[4] = '\0';
// Disconnect Command
if (cmd == DETACH) {
LOGINFO("rasctl command disconnect %s at ID: %d UN: %d", type_str, id, un);
LOGINFO("rasctl command disconnect %s at ID: %d UN: %d", pUnit->GetID().c_str(), id, un);
// Free the existing unit
map[id * UnitNum + un] = NULL;
@ -639,9 +621,8 @@ bool ProcessCmd(int fd, const PbCommand &command)
}
// Valid only for MO or CD
if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O') &&
pUnit->GetID() != MAKEID('S', 'C', 'C', 'D')) {
LOGWARN("rasctl sent an Insert/Eject/Protect command (%d) for incompatible type %s", cmd, type_str);
if (!pUnit->IsMo() && !pUnit->IsCdRom()) {
LOGWARN("rasctl sent an Insert/Eject/Protect command (%d) for incompatible type %s", cmd, pUnit->GetID().c_str());
ostringstream error;
error << "Operation denied (Device type " << type_str << " isn't removable)";
@ -651,7 +632,7 @@ bool ProcessCmd(int fd, const PbCommand &command)
switch (cmd) {
case INSERT:
filepath.SetPath(params.c_str());
LOGINFO("rasctl commanded insert file %s into %s ID: %d UN: %d", params.c_str(), type_str, id, un);
LOGINFO("rasctl commanded insert file %s into %s ID: %d UN: %d", params.c_str(), pUnit->GetID().c_str(), id, un);
if (!pUnit->Open(filepath)) {
ostringstream error;
@ -667,12 +648,12 @@ bool ProcessCmd(int fd, const PbCommand &command)
break;
case PROTECT:
if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O')) {
LOGWARN("rasctl sent an invalid PROTECT command for %s ID: %d UN: %d", type_str, id, un);
if (!pUnit->IsMo()) {
LOGWARN("rasctl sent an invalid PROTECT command for %s ID: %d UN: %d", pUnit->GetID().c_str(), id, un);
return ReturnStatus(fd, false, "Error : Operation denied (Device isn't MO)");
}
LOGINFO("rasctl is setting write protect to %d for %s ID: %d UN: %d",!pUnit->IsWriteP(), type_str, id, un);
LOGINFO("rasctl is setting write protect to %d for %s ID: %d UN: %d",!pUnit->IsWriteP(), pUnit->GetID().c_str(), id, un);
pUnit->WriteP(!pUnit->IsWriteP());
break;

View File

@ -20,13 +20,6 @@
//---------------------------------------------------------------------------
#define RASCSI 1
//---------------------------------------------------------------------------
//
// ID Macro
//
//---------------------------------------------------------------------------
#define MAKEID(a, b, c, d) ((DWORD)((a<<24) | (b<<16) | (c<<8) | d))
//---------------------------------------------------------------------------
//
// Various Operation Settings