From a8ed8ef7c40c9bb46c1331450bdda4d8d61982e3 Mon Sep 17 00:00:00 2001 From: akuker Date: Fri, 28 Aug 2020 11:56:28 -0500 Subject: [PATCH] Start to back out some changes. Just include command processing changes --- src/raspberrypi/Makefile | 1 - src/raspberrypi/command_thread.cpp | 1 - src/raspberrypi/rascsi.cpp | 430 ++++++++++++++++++++++++++--- src/raspberrypi/rascsi_mgr.cpp | 403 --------------------------- src/raspberrypi/rascsi_mgr.h | 84 ------ 5 files changed, 386 insertions(+), 533 deletions(-) delete mode 100644 src/raspberrypi/rascsi_mgr.cpp delete mode 100644 src/raspberrypi/rascsi_mgr.h diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 15c380e..232d6ba 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -54,7 +54,6 @@ SRC_RASCSI = \ gpiobus.cpp \ filepath.cpp \ fileio.cpp\ - rascsi_mgr.cpp\ command_thread.cpp\ os.cpp\ rasctl_command.cpp diff --git a/src/raspberrypi/command_thread.cpp b/src/raspberrypi/command_thread.cpp index 9d9ec6e..5664ea3 100644 --- a/src/raspberrypi/command_thread.cpp +++ b/src/raspberrypi/command_thread.cpp @@ -21,7 +21,6 @@ #include "os.h" #include "rasctl_command.h" -#include "rascsi_mgr.h" #include "sasihd.h" #include "scsihd.h" #include "scsihd_nec.h" diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index 2207d54..537c2b1 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -5,8 +5,6 @@ // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS -// Copyright (C) akuker -// // [ RaSCSI main ] // //--------------------------------------------------------------------------- @@ -27,41 +25,35 @@ #include "controllers/sasidev_ctrl.h" #include "gpiobus.h" #include "command_thread.h" -#include "rascsi_mgr.h" - -#include "sasidev_ctrl.h" -#include "scsidev_ctrl.h" - -#include "sasihd.h" -#include "scsihd.h" -#include "scsihd_apple.h" -#include "scsihd_nec.h" -#include "scsicd.h" -#include "scsimo.h" -#include "scsi_host_bridge.h" - - //--------------------------------------------------------------------------- // // Constant declarations // //--------------------------------------------------------------------------- +#define CtrlMax 8 // Maximum number of SCSI controllers +#define UnitNum 2 // Number of units around controller +#ifdef BAREMETAL +#define FPRT(fp, ...) printf( __VA_ARGS__ ) +#else +#define FPRT(fp, ...) fprintf(fp, __VA_ARGS__ ) +#endif // BAREMETAL //--------------------------------------------------------------------------- // // Variable declarations // //--------------------------------------------------------------------------- +static volatile BOOL running; // Running flag +static volatile BOOL active; // Processing flag +SASIDEV *ctrl[CtrlMax]; // Controller +Disk *disk[CtrlMax * UnitNum]; // Disk +GPIOBUS *bus; // GPIO Bus #ifdef BAREMETAL FATFS fatfs; // FatFS #else #endif // BAREMETAL -#ifndef CONNECT_DESC -#define CONNECT_DESC "UNKNOWN" -#endif - #ifndef BAREMETAL //--------------------------------------------------------------------------- // @@ -71,7 +63,7 @@ FATFS fatfs; // FatFS void KillHandler(int sig) { // Stop instruction - Rascsi_Manager::Stop(); + running = FALSE; } #endif // BAREMETAL @@ -93,7 +85,6 @@ void Banner(int argc, char* argv[]) FPRT(stdout,"Powered by XM6 TypeG Technology / "); FPRT(stdout,"Copyright (C) 2016-2020 GIMONS\n"); FPRT(stdout,"Connect type : %s\n", CONNECT_DESC); - FPRT(stdout,"Build on %s at %s\n", __DATE__, __TIME__); if ((argc > 1 && strcmp(argv[1], "-h") == 0) || (argc > 1 && strcmp(argv[1], "--help") == 0)){ @@ -127,17 +118,9 @@ void Banner(int argc, char* argv[]) //--------------------------------------------------------------------------- BOOL Init() { - printf("Rascsi_Manager Init\n"); - if(!Rascsi_Manager::Init()){ - printf("\tRascsi_Manager FAILED!!\n"); - return FALSE; - } + int i; - printf("Command_Thread Init\n"); - if(!Command_Thread::Init()){ - printf("\tCommand_Thread FAILED!!\n"); - return FALSE; - } +#ifndef BAREMETAL // Interrupt handler settings if (signal(SIGINT, KillHandler) == SIG_ERR) { @@ -149,6 +132,38 @@ BOOL Init() if (signal(SIGTERM, KillHandler) == SIG_ERR) { return FALSE; } +#endif // BAREMETAL + + // GPIOBUS creation + bus = new GPIOBUS(); + + // GPIO Initialization + if (!bus->Init()) { + return FALSE; + } + + // Bus Reset + bus->Reset(); + + // Controller initialization + for (i = 0; i < CtrlMax; i++) { + ctrl[i] = NULL; + } + + // Disk Initialization + for (i = 0; i < CtrlMax; i++) { + disk[i] = NULL; + } + + // Other + running = FALSE; + active = FALSE; + + printf("Command_Thread Init\n"); + if(!Command_Thread::Init()){ + printf("\tCommand_Thread FAILED!!\n"); + return FALSE; + } return TRUE; } @@ -160,13 +175,243 @@ BOOL Init() //--------------------------------------------------------------------------- void Cleanup() { - Rascsi_Manager::Close(); + int i; + + // Delete the disks + for (i = 0; i < CtrlMax * UnitNum; i++) { + if (disk[i]) { + delete disk[i]; + disk[i] = NULL; + } + } + + // Delete the Controllers + for (i = 0; i < CtrlMax; i++) { + if (ctrl[i]) { + delete ctrl[i]; + ctrl[i] = NULL; + } + } + + // Cleanup the Bus + bus->Cleanup(); + + // Discard the GPIOBUS object + delete bus; #ifndef BAREMETAL + // Close the command socket Command_Thread::Close(); #endif // BAREMETAL } +//--------------------------------------------------------------------------- +// +// Reset +// +//--------------------------------------------------------------------------- +void Reset() +{ + int i; + + // Reset all of the controllers + for (i = 0; i < CtrlMax; i++) { + if (ctrl[i]) { + ctrl[i]->Reset(); + } + } + + // Reset the bus + bus->Reset(); +} + +//--------------------------------------------------------------------------- +// +// List Devices +// +//--------------------------------------------------------------------------- +void ListDevice(FILE *fp) +{ + int i; + int id; + int un; + Disk *pUnit; + Filepath filepath; + BOOL find; + char type[5]; + + find = FALSE; + type[4] = 0; + for (i = 0; i < CtrlMax * UnitNum; i++) { + // Initialize ID and unit number + id = i / UnitNum; + un = i % UnitNum; + pUnit = disk[i]; + + // skip if unit does not exist or null disk + if (pUnit == NULL || pUnit->IsNULL()) { + continue; + } + + // Output the header + if (!find) { + FPRT(fp, "\n"); + FPRT(fp, "+----+----+------+-------------------------------------\n"); + FPRT(fp, "| ID | UN | TYPE | DEVICE STATUS\n"); + FPRT(fp, "+----+----+------+-------------------------------------\n"); + find = TRUE; + } + + // ID,UNIT,Type,Device Status + type[0] = (char)(pUnit->GetID() >> 24); + type[1] = (char)(pUnit->GetID() >> 16); + type[2] = (char)(pUnit->GetID() >> 8); + type[3] = (char)(pUnit->GetID()); + FPRT(fp, "| %d | %d | %s | ", id, un, type); + + // mount status output + if (pUnit->GetID() == MAKEID('S', 'C', 'B', 'R')) { + FPRT(fp, "%s", "HOST BRIDGE"); + } else { + pUnit->GetPath(filepath); + FPRT(fp, "%s", + (pUnit->IsRemovable() && !pUnit->IsReady()) ? + "NO MEDIA" : filepath.GetPath()); + } + + // Write protection status + if (pUnit->IsRemovable() && pUnit->IsReady() && pUnit->IsWriteP()) { + FPRT(fp, "(WRITEPROTECT)"); + } + + // Goto the next line + FPRT(fp, "\n"); + } + + // If there is no controller, find will be null + if (!find) { + FPRT(fp, "No device is installed.\n"); + return; + } + + FPRT(fp, "+----+----+------+-------------------------------------\n"); +} + +//--------------------------------------------------------------------------- +// +// Controller Mapping +// +//--------------------------------------------------------------------------- +void MapControler(FILE *fp, Disk **map) +{ + int i; + int j; + int unitno; + int sasi_num; + int scsi_num; + + // Replace the changed unit + for (i = 0; i < CtrlMax; i++) { + for (j = 0; j < UnitNum; j++) { + unitno = i * UnitNum + j; + if (disk[unitno] != map[unitno]) { + // Check if the original unit exists + if (disk[unitno]) { + // Disconnect it from the controller + if (ctrl[i]) { + ctrl[i]->SetUnit(j, NULL); + } + + // Free the Unit + delete disk[unitno]; + } + + // Setup a new unit + disk[unitno] = map[unitno]; + } + } + } + + // Reconfigure all of the controllers + for (i = 0; i < CtrlMax; i++) { + // Examine the unit configuration + sasi_num = 0; + scsi_num = 0; + for (j = 0; j < UnitNum; j++) { + unitno = i * UnitNum + j; + // branch by unit type + if (disk[unitno]) { + if (disk[unitno]->IsSASI()) { + // Drive is SASI, so increment SASI count + sasi_num++; + } else { + // Drive is SCSI, so increment SCSI count + scsi_num++; + } + } + + // Remove the unit + if (ctrl[i]) { + ctrl[i]->SetUnit(j, NULL); + } + } + + // If there are no units connected + if (sasi_num == 0 && scsi_num == 0) { + if (ctrl[i]) { + delete ctrl[i]; + ctrl[i] = NULL; + continue; + } + } + + // Mixture of SCSI and SASI + if (sasi_num > 0 && scsi_num > 0) { + FPRT(fp, "Error : SASI and SCSI can't be mixed\n"); + continue; + } + + if (sasi_num > 0) { + // Only SASI Unit(s) + + // Release the controller if it is not SASI + if (ctrl[i] && !ctrl[i]->IsSASI()) { + delete ctrl[i]; + ctrl[i] = NULL; + } + + // Create a new SASI controller + if (!ctrl[i]) { + ctrl[i] = new SASIDEV(); + ctrl[i]->Connect(i, bus); + } + } else { + // Only SCSI Unit(s) + + // Release the controller if it is not SCSI + if (ctrl[i] && !ctrl[i]->IsSCSI()) { + delete ctrl[i]; + ctrl[i] = NULL; + } + + // Create a new SCSI controller + if (!ctrl[i]) { + ctrl[i] = new SCSIDEV(); + ctrl[i]->Connect(i, bus); + } + } + + // connect all units + for (j = 0; j < UnitNum; j++) { + unitno = i * UnitNum + j; + if (disk[unitno]) { + // Add the unit connection + ctrl[i]->SetUnit(j, disk[unitno]); + } + } + } +} + //--------------------------------------------------------------------------- // // Main processing @@ -181,9 +426,13 @@ int startrascsi(void) #else int main(int argc, char* argv[]) { - int i=0; #endif // BAREMETAL + int i; int ret; + int actid; + DWORD now; + BUS::phase_t phase; + BYTE data; #ifndef BAREMETAL struct sched_param schparam; #endif // BAREMETAL @@ -198,24 +447,23 @@ int main(int argc, char* argv[]) goto init_exit; } + // Reset + Reset(); #ifdef BAREMETAL // BUSY assert (to hold the host side) - Rascsi_Manager::m_bus->SetBSY(TRUE); + bus->SetBSY(TRUE); // Argument parsing if (!Command_Thread::ParseConfig(argc, argv)) { ret = EINVAL; goto err_exit; } + // Release the busy signal - Rascsi_Manager::m_bus->SetBSY(FALSE); - + bus->SetBSY(FALSE); #endif - // For non-baremetal versions, we won't process the startup arguments... yet - printf("Here1\n"); - #ifndef BAREMETAL // Set the affinity to a specific processor core FixCpu(3); @@ -227,11 +475,105 @@ int main(int argc, char* argv[]) #endif // USE_SEL_EVENT_ENABLE #endif // BAREMETAL - printf("entering main loop \n"); + // Start execution + running = TRUE; + // Main Loop - while (Rascsi_Manager::IsRunning()) { - printf("step %d\n", i++); - Rascsi_Manager::Step(); + while (running) { + // Work initialization + actid = -1; + phase = BUS::busfree; + +#ifdef USE_SEL_EVENT_ENABLE + // SEL signal polling + if (bus->PollSelectEvent() < 0) { + // Stop on interrupt + if (errno == EINTR) { + break; + } + continue; + } + + // Get the bus + bus->Aquire(); +#else + bus->Aquire(); + if (!bus->GetSEL()) { +#if !defined(BAREMETAL) + usleep(0); +#endif // !BAREMETAL + continue; + } +#endif // USE_SEL_EVENT_ENABLE + + // Wait until BSY is released as there is a possibility for the + // initiator to assert it while setting the ID (for up to 3 seconds) + if (bus->GetBSY()) { + now = SysTimer::GetTimerLow(); + while ((SysTimer::GetTimerLow() - now) < 3 * 1000 * 1000) { + bus->Aquire(); + if (!bus->GetBSY()) { + break; + } + } + } + + // Stop because it the bus is busy or another device responded + if (bus->GetBSY() || !bus->GetSEL()) { + continue; + } + + // Notify all controllers + data = bus->GetDAT(); + for (i = 0; i < CtrlMax; i++) { + if (!ctrl[i] || (data & (1 << i)) == 0) { + continue; + } + + // Find the target that has moved to the selection phase + if (ctrl[i]->Process() == BUS::selection) { + // Get the target ID + actid = i; + + // Bus Selection phase + phase = BUS::selection; + break; + } + } + + // Return to bus monitoring if the selection phase has not started + if (phase != BUS::selection) { + continue; + } + + // Start target device + active = TRUE; + +#if !defined(USE_SEL_EVENT_ENABLE) && !defined(BAREMETAL) + // Scheduling policy setting (highest priority) + schparam.sched_priority = sched_get_priority_max(SCHED_FIFO); + sched_setscheduler(0, SCHED_FIFO, &schparam); +#endif // !USE_SEL_EVENT_ENABLE && !BAREMETAL + + // Loop until the bus is free + while (running) { + // Target drive + phase = ctrl[actid]->Process(); + + // End when the bus is free + if (phase == BUS::busfree) { + break; + } + } + +#if !defined(USE_SEL_EVENT_ENABLE) && !defined(BAREMETAL) + // Set the scheduling priority back to normal + schparam.sched_priority = 0; + sched_setscheduler(0, SCHED_OTHER, &schparam); +#endif // !USE_SEL_EVENT_ENABLE && !BAREMETAL + + // End the target travel + active = FALSE; } printf("Exited main loop\n"); diff --git a/src/raspberrypi/rascsi_mgr.cpp b/src/raspberrypi/rascsi_mgr.cpp deleted file mode 100644 index 212641a..0000000 --- a/src/raspberrypi/rascsi_mgr.cpp +++ /dev/null @@ -1,403 +0,0 @@ -#include "rascsi_mgr.h" -#include "log.h" -#include "sasidev_ctrl.h" -#include "scsidev_ctrl.h" - -SASIDEV *Rascsi_Manager::m_ctrl[CtrlMax]; // Controller -Disk *Rascsi_Manager::m_disk[CtrlMax * UnitNum]; // Disk -GPIOBUS *Rascsi_Manager::m_bus; - -int Rascsi_Manager::m_actid = -1; -BUS::phase_t Rascsi_Manager::m_phase = BUS::busfree; -BYTE Rascsi_Manager::m_data = 0; -DWORD Rascsi_Manager::m_now = 0; -BOOL Rascsi_Manager::m_active = FALSE; -BOOL Rascsi_Manager::m_running = FALSE; -std::timed_mutex Rascsi_Manager::m_locked; -BOOL Rascsi_Manager::m_initialized = FALSE; - -BOOL Rascsi_Manager::AttachDevice(FILE *fp, Disk *disk, int id, int unit_num){ - BOOL result; - m_locked.lock(); - result = AttachDevicePrivate(fp, disk, id, unit_num); - m_locked.unlock(); - return result; -} - -BOOL Rascsi_Manager::DetachDevice(FILE *fp, int id, int unit_num){ - BOOL result; - m_locked.lock(); - result = DetachDevicePrivate(fp, id, unit_num); - m_locked.unlock(); - return result; -} - -BOOL Rascsi_Manager::AttachDevicePrivate(FILE *fp, Disk *disk, int id, int unit_num) -{ - Rascsi_Device_Mode_e cur_mode = GetCurrentDeviceMode(); - int unitno = (id * UnitNum) + unit_num; - - if((disk->IsSASI() && (cur_mode == rascsi_device_scsi_mode)) || - (!disk->IsSCSI() && (cur_mode == rascsi_device_sasi_mode))){ - FPRT(fp, "Warning: Can't mix SASI and SCSI devices!\n"); - return FALSE; - } - - // Check if something already exists at that SCSI ID / Unit Number - if (m_disk[unitno]) { - DetachDevicePrivate(fp,id,unit_num); - } - - // Add the new unit - m_disk[unitno] = disk; - - // If the controllder doesn't already exist, create it. - if (m_ctrl[id] == nullptr){ - // We need to create a new controller - if(disk->IsSASI()){ - m_ctrl[id] = new SASIDEV(); - }else{ - m_ctrl[id] = new SCSIDEV(); - } - m_ctrl[id]->Connect(id, m_bus); - } - - // Add the disk to the controller - m_ctrl[id]->SetUnit(unit_num, disk); - return TRUE; -} - -BOOL Rascsi_Manager::DetachDevicePrivate(FILE *fp, int id, int unit_num) -{ - int unitno = (id * UnitNum) + unit_num; - - // Disconnect it from the controller - if (m_ctrl[id]) { - m_ctrl[id]->SetUnit(unit_num, NULL); - // Free the Unit - delete m_disk[unitno]; - m_disk[unitno] = nullptr; - }else{ - fprintf(fp, "Warning: A controller was not connected to the drive at id %d un %d\n",id, unit_num); - fprintf(fp, "This is some sort of internal error, since you can't have a device without a controller.\n"); - return FALSE; - } - - // If there are no longer any units connected to this controller, delete it - if(!m_ctrl[id]->HasUnit()){ - delete m_ctrl[id]; - m_ctrl[id] = nullptr; - } - - return TRUE; -} - -Disk* Rascsi_Manager::GetDevice(FILE *fp, int id, int unit_num) -{ - int unitno = (id * UnitNum) + unit_num; - return m_disk[unitno]; -} - -//--------------------------------------------------------------------------- -// -// GetCurrentDeviceMode -// -// Loop through all of the controllers and check if we have SCSI or SASI -// controllers already created. (Note: We can't have a mix of them) -// -//--------------------------------------------------------------------------- -Rascsi_Device_Mode_e Rascsi_Manager::GetCurrentDeviceMode(){ - - Rascsi_Device_Mode_e mode = rascsi_device_unknown_mode; - for(int i =0; i < CtrlMax; i++){ - if(m_ctrl[i] != nullptr){ - if(m_ctrl[i]->IsSASI()){ - if(mode == rascsi_device_unknown_mode){ - mode = rascsi_device_sasi_mode; - }else if(mode == rascsi_device_scsi_mode){ - mode = rascsi_device_invalid_mode; - printf("Error: Mix of SCSI and SASI devices. This isn't allowed. Device %d was SASI, but expecting SCSI\n", i); - } - }else { // This is SCSI - if(mode == rascsi_device_unknown_mode){ - mode = rascsi_device_scsi_mode; - }else if(mode == rascsi_device_sasi_mode){ - mode = rascsi_device_invalid_mode; - printf("Error: Mix of SCSI and SASI devices. This isn't allowed. Device %d was SCSI, but expecting SASI\n", i); - } - } - } - } - return mode; -} - - - -//--------------------------------------------------------------------------- -// -// Reset -// -//--------------------------------------------------------------------------- -void Rascsi_Manager::Reset() -{ - int i; - - // Reset all of the controllers - for (i = 0; i < CtrlMax; i++) { - if (m_ctrl[i]) { - m_ctrl[i]->Reset(); - } - } - - // Reset the bus - m_bus->Reset(); -} - -//--------------------------------------------------------------------------- -// -// List Devices -// -//--------------------------------------------------------------------------- -void Rascsi_Manager::ListDevice(FILE *fp) -{ - int i; - int id; - int un; - Disk *pUnit; - Filepath filepath; - BOOL find; - char type[5]; - - find = FALSE; - type[4] = 0; - for (i = 0; i < CtrlMax * UnitNum; i++) { - // Initialize ID and unit number - id = i / UnitNum; - un = i % UnitNum; - pUnit = m_disk[i]; - - // skip if unit does not exist or null disk - if (pUnit == NULL || pUnit->IsNULL()) { - continue; - } - - // Output the header - if (!find) { - FPRT(fp, "\n"); - FPRT(fp, "+----+----+------+-------------------------------------\n"); - FPRT(fp, "| ID | UN | TYPE | DEVICE STATUS\n"); - FPRT(fp, "+----+----+------+-------------------------------------\n"); - find = TRUE; - } - - // ID,UNIT,Type,Device Status - type[0] = (char)(pUnit->GetID() >> 24); - type[1] = (char)(pUnit->GetID() >> 16); - type[2] = (char)(pUnit->GetID() >> 8); - type[3] = (char)(pUnit->GetID()); - FPRT(fp, "| %d | %d | %s | ", id, un, type); - - // mount status output - if (pUnit->GetID() == MAKEID('S', 'C', 'B', 'R')) { - FPRT(fp, "%s", "HOST BRIDGE"); - } else { - pUnit->GetPath(filepath); - FPRT(fp, "%s", - (pUnit->IsRemovable() && !pUnit->IsReady()) ? - "NO MEDIA" : filepath.GetPath()); - } - - // Write protection status - if (pUnit->IsRemovable() && pUnit->IsReady() && pUnit->IsWriteP()) { - FPRT(fp, "(WRITEPROTECT)"); - } - - // Goto the next line - FPRT(fp, "\n"); - } - - // If there is no controller, find will be null - if (!find) { - FPRT(fp, "No device is installed.\n"); - return; - } - - FPRT(fp, "+----+----+------+-------------------------------------\n"); -} - -void Rascsi_Manager::Close(){ - // Delete the disks - for (int i = 0; i < (CtrlMax * UnitNum); i++) { - if (m_disk[i]) { - delete m_disk[i]; - m_disk[i] = NULL; - } - } - - // Delete the Controllers - for (int i = 0; i < CtrlMax; i++) { - if (m_ctrl[i]) { - delete m_ctrl[i]; - m_ctrl[i] = NULL; - } - } - - // Cleanup the Bus - m_bus->Cleanup(); - - // Discard the GPIOBUS object - delete m_bus; -} - -BOOL Rascsi_Manager::Init(){ - - if(m_initialized != FALSE){ - printf("Can not initialize Rascsi_Manager twice!!!\n"); - return FALSE; - } - m_initialized = TRUE; - - // GPIOBUS creation - m_bus = new GPIOBUS(); - - // GPIO Initialization - if (!m_bus->Init()) { - return FALSE; - } - - // Bus Reset - m_bus->Reset(); - - // Controller initialization - for (int i = 0; i < CtrlMax; i++) { - m_ctrl[i] = NULL; - } - - // Disk Initialization - for (int i = 0; i < CtrlMax; i++) { - m_disk[i] = NULL; - } - - // Reset - Reset(); - - m_running = TRUE; - - return TRUE; -} - - - -BOOL Rascsi_Manager::Step() -{ - - // Work initialization - m_actid = -1; - m_phase = BUS::busfree; - -#ifdef USE_SEL_EVENT_ENABLE - // SEL signal polling - if (m_bus->PollSelectEvent() < 0) { - // Stop on interrupt - if (errno == EINTR) { - m_locked.unlock(); - return FALSE; - } - return FALSE; - } - - // Get the bus - m_bus->Aquire(); -#else - m_bus->Aquire(); - if (!m_bus->GetSEL()) { -#if !defined(BAREMETAL) - usleep(0); -#endif // !BAREMETAL - return FALSE; - } -#endif // USE_SEL_EVENT_ENABLE - - // Wait until BSY is released as there is a possibility for the - // initiator to assert it while setting the ID (for up to 3 seconds) - if (m_bus->GetBSY()) { - m_now = SysTimer::GetTimerLow(); - while ((SysTimer::GetTimerLow() - m_now) < 3 * 1000 * 1000) { - m_bus->Aquire(); - if (!m_bus->GetBSY()) { - break; - } - } - } - - // Stop because it the bus is busy or another device responded - if (m_bus->GetBSY() || !m_bus->GetSEL()) { - return FALSE; - } - - m_locked.lock(); - // Notify all controllers - m_data = m_bus->GetDAT(); - for (int i = 0; i < CtrlMax; i++) { - if (!m_ctrl[i] || (m_data & (1 << i)) == 0) { - continue; - } - - // Find the target that has moved to the selection phase - if (m_ctrl[i]->Process() == BUS::selection) { - // Get the target ID - m_actid = i; - - // Bus Selection phase - m_phase = BUS::selection; - break; - } - } - - // Return to bus monitoring if the selection phase has not started - if (m_phase != BUS::selection) { - m_locked.unlock(); - return FALSE; - } - - // Start target device - m_active = TRUE; - -#if !defined(USE_SEL_EVENT_ENABLE) && !defined(BAREMETAL) - // Scheduling policy setting (highest priority) - schparam.sched_priority = sched_get_priority_max(SCHED_FIFO); - sched_setscheduler(0, SCHED_FIFO, &schparam); -#endif // !USE_SEL_EVENT_ENABLE && !BAREMETAL - - // Loop until the bus is free - while (m_running) { - // Target drive - m_phase = m_ctrl[m_actid]->Process(); - - // End when the bus is free - if (m_phase == BUS::busfree) { - break; - } - } - -#if !defined(USE_SEL_EVENT_ENABLE) && !defined(BAREMETAL) - // Set the scheduling priority back to normal - schparam.sched_priority = 0; - sched_setscheduler(0, SCHED_OTHER, &schparam); -#endif // !USE_SEL_EVENT_ENABLE && !BAREMETAL - - // End the target travel - m_active = FALSE; - - m_locked.unlock(); - return TRUE; - -} - - -void Rascsi_Manager::Stop(){ - m_running = FALSE; -} -BOOL Rascsi_Manager::IsRunning(){ - return (m_running == TRUE); -} diff --git a/src/raspberrypi/rascsi_mgr.h b/src/raspberrypi/rascsi_mgr.h deleted file mode 100644 index 06bac9d..0000000 --- a/src/raspberrypi/rascsi_mgr.h +++ /dev/null @@ -1,84 +0,0 @@ -//--------------------------------------------------------------------------- -// -// SCSI Target Emulator RaSCSI (*^..^*) -// for Raspberry Pi -// -// Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker -// -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. -// -// [ RaSCSI Manager ] -// -// Any meaningful logic should be included in this file so that it can be -// tested using unit tests. The main "rascsi.cpp" file should contain very -// little functional code. -//--------------------------------------------------------------------------- -#pragma once - -#include "os.h" -#include "scsi.h" -#include "fileio.h" -#include "disk.h" -#include "log.h" -#include "xm6.h" -#include "gpiobus.h" -#include "sasidev_ctrl.h" -#include - -enum Rascsi_Device_Mode_e{ - rascsi_device_unknown_mode, - rascsi_device_sasi_mode, - rascsi_device_scsi_mode, - rascsi_device_invalid_mode, -}; - -class Rascsi_Manager{ - public: - static Rascsi_Manager* GetInstance(); - static void MapControler(FILE *fp, Disk **map); - - static void Stop(); - static BOOL IsRunning(); - - static BOOL AttachDevice(FILE *fp, Disk *disk, int id, int ui); - static BOOL DetachDevice(FILE *fp, int id, int ui); - static Disk* GetDevice(FILE *fp, int id, int ui); - static void ListDevice(FILE *fp); - static BOOL Init(); - static void Close(); - static void Reset(); - static BOOL Step(); - static Rascsi_Device_Mode_e GetCurrentDeviceMode(); - - static const int CtrlMax = 8; // Maximum number of SCSI controllers - static const int UnitNum=2; // Number of units around controller - - - // TODO: These need to be made private. All of the functionality that is using - // them directly should be updated to be issolated. - // The Command_Thread class is WAAAAY too tightly coupled to this class. - // - static SASIDEV *m_ctrl[CtrlMax]; // Controller - static Disk *m_disk[CtrlMax * UnitNum]; // Disk - static GPIOBUS *m_bus; // GPIO Bus - - - private: - static int m_actid; - static BUS::phase_t m_phase; - static BYTE m_data; - static DWORD m_now; - static BOOL m_active; - static BOOL m_running; - static BOOL m_initialized; - - static BOOL AttachDevicePrivate(FILE *fp, Disk *disk, int id, int ui); - static BOOL DetachDevicePrivate(FILE *fp, int id, int ui); - - // Any PUBLIC functions should lock this before accessing the m_ctrl - // m_disk or m_bus data structures. The Public functions could be - // called from a different thread. - static std::timed_mutex m_locked; -};