mirror of
https://github.com/thewesker/RASCSI.git
synced 2025-12-21 04:41:12 -05:00
Additional changes.... command interface works?
This commit is contained in:
@@ -1,7 +1,26 @@
|
|||||||
#include "os.h"
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// [ Command thread ]
|
||||||
|
//
|
||||||
|
// This is a background thread that runs, listening for commands on port
|
||||||
|
// 6868 for commands from the rasctl utility. This also includes the logic
|
||||||
|
// for handling the initialization commands that are specified at startup.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "rasctl_command.h"
|
|
||||||
#include "command_thread.h"
|
#include "command_thread.h"
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
#include "rasctl_command.h"
|
||||||
#include "rascsi_mgr.h"
|
#include "rascsi_mgr.h"
|
||||||
#include "sasihd.h"
|
#include "sasihd.h"
|
||||||
#include "scsihd.h"
|
#include "scsihd.h"
|
||||||
@@ -11,23 +30,9 @@
|
|||||||
#include "scsimo.h"
|
#include "scsimo.h"
|
||||||
#include "scsi_host_bridge.h"
|
#include "scsi_host_bridge.h"
|
||||||
|
|
||||||
BOOL Command_Thread::m_running = FALSE;
|
|
||||||
int Command_Thread::m_monsocket = -1; // Monitor Socket
|
int Command_Thread::m_monsocket = -1; // Monitor Socket
|
||||||
pthread_t Command_Thread::m_monthread; // Monitor Thread
|
pthread_t Command_Thread::m_monthread; // Monitor Thread
|
||||||
|
|
||||||
|
|
||||||
void Command_Thread::Start(){
|
|
||||||
m_running = TRUE;
|
|
||||||
}
|
|
||||||
void Command_Thread::Stop(){
|
|
||||||
m_running = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL Command_Thread::IsRunning(){
|
|
||||||
return m_running;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Initialization
|
// Initialization
|
||||||
@@ -44,7 +49,7 @@ BOOL Command_Thread::Init()
|
|||||||
m_monsocket = socket(PF_INET, SOCK_STREAM, 0);
|
m_monsocket = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
memset(&server, 0, sizeof(server));
|
memset(&server, 0, sizeof(server));
|
||||||
server.sin_family = PF_INET;
|
server.sin_family = PF_INET;
|
||||||
server.sin_port = htons(6868);
|
server.sin_port = htons(Rasctl_Command::PortNumber);
|
||||||
server.sin_addr.s_addr = htonl(INADDR_ANY);
|
server.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
|
||||||
// allow address reuse
|
// allow address reuse
|
||||||
@@ -70,6 +75,11 @@ BOOL Command_Thread::Init()
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Close/Cleanup the command thread
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void Command_Thread::Close(){
|
void Command_Thread::Close(){
|
||||||
// Close the monitor socket
|
// Close the monitor socket
|
||||||
if (m_monsocket >= 0) {
|
if (m_monsocket >= 0) {
|
||||||
@@ -292,15 +302,10 @@ void *Command_Thread::MonThread(void *param)
|
|||||||
// Set the affinity to a specific processor core
|
// Set the affinity to a specific processor core
|
||||||
FixCpu(2);
|
FixCpu(2);
|
||||||
|
|
||||||
// Wait for the execution to start
|
|
||||||
while (!m_running) {
|
|
||||||
usleep(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup the monitor socket to receive commands
|
// Setup the monitor socket to receive commands
|
||||||
listen(m_monsocket, 1);
|
listen(m_monsocket, 1);
|
||||||
|
|
||||||
while (1) {
|
while (Rascsi_Manager::IsRunning()) {
|
||||||
// Wait for connection
|
// Wait for connection
|
||||||
memset(&client, 0, sizeof(client));
|
memset(&client, 0, sizeof(client));
|
||||||
len = sizeof(client);
|
len = sizeof(client);
|
||||||
@@ -316,16 +321,7 @@ void *Command_Thread::MonThread(void *param)
|
|||||||
// If we received a command....
|
// If we received a command....
|
||||||
if (p) {
|
if (p) {
|
||||||
|
|
||||||
// // Remove the newline character
|
new_command = Rasctl_Command::DeSerialize(p,BUFSIZ);
|
||||||
// p[strlen(p) - 1] = 0;
|
|
||||||
|
|
||||||
// // List all of the devices
|
|
||||||
// if (xstrncasecmp(p, "list", 4) == 0) {
|
|
||||||
// Rascsi_Manager::GetInstance()->ListDevice(fp);
|
|
||||||
// goto next;
|
|
||||||
// }
|
|
||||||
|
|
||||||
new_command = Rasctl_Command::DeSerialize((BYTE*)p,BUFSIZ);
|
|
||||||
|
|
||||||
if(new_command != nullptr){
|
if(new_command != nullptr){
|
||||||
// Execute the command
|
// Execute the command
|
||||||
@@ -377,22 +373,20 @@ BOOL Command_Thread::ExecuteCommand(FILE *fp, Rasctl_Command *incoming_command)
|
|||||||
result = DoDetach(fp,incoming_command);
|
result = DoDetach(fp,incoming_command);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("UNKNOWN COMMAND RECEIVED\n");
|
fprintf(fp, "UNKNOWN COMMAND RECEIVED\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!result){
|
|
||||||
fputs("Unknown server error", fp);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL Command_Thread::DoShutdown(FILE *fp, Rasctl_Command *incoming_command){
|
BOOL Command_Thread::DoShutdown(FILE *fp, Rasctl_Command *incoming_command){
|
||||||
m_running = FALSE;
|
fprintf(fp, "Stopping the RaSCSI application\n");
|
||||||
|
Rascsi_Manager::Stop();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL Command_Thread::DoList(FILE *fp, Rasctl_Command *incoming_command){
|
BOOL Command_Thread::DoList(FILE *fp, Rasctl_Command *incoming_command){
|
||||||
Rascsi_Manager::GetInstance()->ListDevice(fp);
|
Rascsi_Manager::ListDevice(fp);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,13 +399,13 @@ BOOL Command_Thread::DoAttach(FILE *fp, Rasctl_Command *incoming_command){
|
|||||||
case rasctl_dev_sasi_hd: // HDF
|
case rasctl_dev_sasi_hd: // HDF
|
||||||
pUnit = new SASIHD();
|
pUnit = new SASIHD();
|
||||||
break;
|
break;
|
||||||
case rasctl_dev_scsi_hd: // HDS/HDN/HDI/NHD/HDA
|
case rasctl_dev_scsi_hd: // HDS/HDI
|
||||||
pUnit = new SCSIHD();
|
pUnit = new SCSIHD();
|
||||||
break;
|
break;
|
||||||
case rasctl_dev_scsi_hd_appl:
|
case rasctl_dev_scsi_hd_appl: // HDA
|
||||||
pUnit = new SCSIHD_APPLE();
|
pUnit = new SCSIHD_APPLE();
|
||||||
break;
|
break;
|
||||||
case rasctl_dev_scsi_hd_nec:
|
case rasctl_dev_scsi_hd_nec: // HDN/NHD
|
||||||
pUnit = new SCSIHD_NEC();
|
pUnit = new SCSIHD_NEC();
|
||||||
break;
|
break;
|
||||||
case rasctl_dev_mo:
|
case rasctl_dev_mo:
|
||||||
@@ -436,6 +430,7 @@ BOOL Command_Thread::DoAttach(FILE *fp, Rasctl_Command *incoming_command){
|
|||||||
case rasctl_dev_scsi_hd:
|
case rasctl_dev_scsi_hd:
|
||||||
case rasctl_dev_cd:
|
case rasctl_dev_cd:
|
||||||
case rasctl_dev_scsi_hd_appl:
|
case rasctl_dev_scsi_hd_appl:
|
||||||
|
if((incoming_command->file != nullptr) && (strnlen(incoming_command->file,_MAX_PATH) > 0)){
|
||||||
// Set the Path
|
// Set the Path
|
||||||
filepath.SetPath(incoming_command->file);
|
filepath.SetPath(incoming_command->file);
|
||||||
|
|
||||||
@@ -445,6 +440,8 @@ BOOL Command_Thread::DoAttach(FILE *fp, Rasctl_Command *incoming_command){
|
|||||||
delete pUnit;
|
delete pUnit;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case rasctl_dev_br:
|
case rasctl_dev_br:
|
||||||
case rasctl_dev_invalid:
|
case rasctl_dev_invalid:
|
||||||
@@ -457,17 +454,17 @@ BOOL Command_Thread::DoAttach(FILE *fp, Rasctl_Command *incoming_command){
|
|||||||
pUnit->SetCacheWB(FALSE);
|
pUnit->SetCacheWB(FALSE);
|
||||||
|
|
||||||
// Map the controller
|
// Map the controller
|
||||||
return Rascsi_Manager::GetInstance()->AttachDevice(fp, pUnit, incoming_command->id, incoming_command->un);
|
return Rascsi_Manager::AttachDevice(fp, pUnit, incoming_command->id, incoming_command->un);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL Command_Thread::DoDetach(FILE *fp, Rasctl_Command *incoming_command){
|
BOOL Command_Thread::DoDetach(FILE *fp, Rasctl_Command *incoming_command){
|
||||||
return Rascsi_Manager::GetInstance()->DetachDevice(fp, incoming_command->id, incoming_command->un);
|
return Rascsi_Manager::DetachDevice(fp, incoming_command->id, incoming_command->un);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL Command_Thread::DoInsert(FILE *fp, Rasctl_Command *incoming_command){
|
BOOL Command_Thread::DoInsert(FILE *fp, Rasctl_Command *incoming_command){
|
||||||
|
|
||||||
Filepath filepath;
|
Filepath filepath;
|
||||||
Disk *pUnit = Rascsi_Manager::GetInstance()->GetDevice(fp, incoming_command->id, incoming_command->un);
|
Disk *pUnit = Rascsi_Manager::GetDevice(fp, incoming_command->id, incoming_command->un);
|
||||||
|
|
||||||
|
|
||||||
// Does the device exist?
|
// Does the device exist?
|
||||||
@@ -495,7 +492,7 @@ BOOL Command_Thread::DoInsert(FILE *fp, Rasctl_Command *incoming_command){
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
BOOL Command_Thread::DoEject(FILE *fp, Rasctl_Command *incoming_command){
|
BOOL Command_Thread::DoEject(FILE *fp, Rasctl_Command *incoming_command){
|
||||||
Disk *pUnit = Rascsi_Manager::GetInstance()->GetDevice(fp, incoming_command->id, incoming_command->un);
|
Disk *pUnit = Rascsi_Manager::GetDevice(fp, incoming_command->id, incoming_command->un);
|
||||||
|
|
||||||
// Does the device exist?
|
// Does the device exist?
|
||||||
if (pUnit == nullptr) {
|
if (pUnit == nullptr) {
|
||||||
@@ -515,7 +512,7 @@ BOOL Command_Thread::DoEject(FILE *fp, Rasctl_Command *incoming_command){
|
|||||||
|
|
||||||
BOOL Command_Thread::DoProtect(FILE *fp, Rasctl_Command *incoming_command){
|
BOOL Command_Thread::DoProtect(FILE *fp, Rasctl_Command *incoming_command){
|
||||||
|
|
||||||
Disk *pUnit = Rascsi_Manager::GetInstance()->GetDevice(fp, incoming_command->id, incoming_command->un);
|
Disk *pUnit = Rascsi_Manager::GetDevice(fp, incoming_command->id, incoming_command->un);
|
||||||
|
|
||||||
// Does the device exist?
|
// Does the device exist?
|
||||||
if (pUnit == nullptr) {
|
if (pUnit == nullptr) {
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ class Command_Thread{
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static BOOL Init();
|
static BOOL Init();
|
||||||
static void Start();
|
|
||||||
static void Stop();
|
|
||||||
static BOOL IsRunning();
|
|
||||||
static void Close();
|
static void Close();
|
||||||
static void KillHandler();
|
static void KillHandler();
|
||||||
static BOOL ParseArgument(int argc, char* argv[]);
|
static BOOL ParseArgument(int argc, char* argv[]);
|
||||||
@@ -40,7 +37,7 @@ class Command_Thread{
|
|||||||
private:
|
private:
|
||||||
static int m_monsocket; // Monitor Socket
|
static int m_monsocket; // Monitor Socket
|
||||||
static pthread_t m_monthread; // Monitor Thread
|
static pthread_t m_monthread; // Monitor Thread
|
||||||
static BOOL m_running;
|
static uint16_t m_monitor_port_num; // Port number to listen for commands
|
||||||
|
|
||||||
static BOOL HasSuffix(const char* string, const char* suffix);
|
static BOOL HasSuffix(const char* string, const char* suffix);
|
||||||
static BOOL DoShutdown(FILE *fp, Rasctl_Command *incoming_command);
|
static BOOL DoShutdown(FILE *fp, Rasctl_Command *incoming_command);
|
||||||
|
|||||||
@@ -56,7 +56,6 @@
|
|||||||
FATFS fatfs; // FatFS
|
FATFS fatfs; // FatFS
|
||||||
#else
|
#else
|
||||||
#endif // BAREMETAL
|
#endif // BAREMETAL
|
||||||
Rascsi_Manager *mgr;
|
|
||||||
|
|
||||||
#ifndef CONNECT_DESC
|
#ifndef CONNECT_DESC
|
||||||
#define CONNECT_DESC "UNKNOWN"
|
#define CONNECT_DESC "UNKNOWN"
|
||||||
@@ -71,7 +70,7 @@ Rascsi_Manager *mgr;
|
|||||||
void KillHandler(int sig)
|
void KillHandler(int sig)
|
||||||
{
|
{
|
||||||
// Stop instruction
|
// Stop instruction
|
||||||
Command_Thread::Stop();
|
Rascsi_Manager::Stop();
|
||||||
}
|
}
|
||||||
#endif // BAREMETAL
|
#endif // BAREMETAL
|
||||||
|
|
||||||
@@ -127,12 +126,11 @@ void Banner(int argc, char* argv[])
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
BOOL Init()
|
BOOL Init()
|
||||||
{
|
{
|
||||||
if(!Command_Thread::Init()){
|
if(!Rascsi_Manager::Init()){
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mgr = Rascsi_Manager::GetInstance();
|
if(!Command_Thread::Init()){
|
||||||
if(!mgr->Init()){
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +155,7 @@ BOOL Init()
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void Cleanup()
|
void Cleanup()
|
||||||
{
|
{
|
||||||
mgr->Close();
|
Rascsi_Manager::Close();
|
||||||
|
|
||||||
#ifndef BAREMETAL
|
#ifndef BAREMETAL
|
||||||
Command_Thread::Close();
|
Command_Thread::Close();
|
||||||
@@ -223,12 +221,9 @@ int main(int argc, char* argv[])
|
|||||||
#endif // USE_SEL_EVENT_ENABLE
|
#endif // USE_SEL_EVENT_ENABLE
|
||||||
#endif // BAREMETAL
|
#endif // BAREMETAL
|
||||||
|
|
||||||
// Start execution
|
|
||||||
Command_Thread::Start();
|
|
||||||
|
|
||||||
// Main Loop
|
// Main Loop
|
||||||
while (Command_Thread::IsRunning()) {
|
while (Rascsi_Manager::IsRunning()) {
|
||||||
mgr->Step();
|
Rascsi_Manager::Step();
|
||||||
}
|
}
|
||||||
#ifdef BAREMETAL
|
#ifdef BAREMETAL
|
||||||
err_exit:
|
err_exit:
|
||||||
|
|||||||
@@ -3,9 +3,6 @@
|
|||||||
#include "sasidev_ctrl.h"
|
#include "sasidev_ctrl.h"
|
||||||
#include "scsidev_ctrl.h"
|
#include "scsidev_ctrl.h"
|
||||||
|
|
||||||
Rascsi_Manager *Rascsi_Manager::m_instance = (Rascsi_Manager*)nullptr;
|
|
||||||
|
|
||||||
|
|
||||||
SASIDEV *Rascsi_Manager::m_ctrl[CtrlMax]; // Controller
|
SASIDEV *Rascsi_Manager::m_ctrl[CtrlMax]; // Controller
|
||||||
Disk *Rascsi_Manager::m_disk[CtrlMax * UnitNum]; // Disk
|
Disk *Rascsi_Manager::m_disk[CtrlMax * UnitNum]; // Disk
|
||||||
GPIOBUS *Rascsi_Manager::m_bus;
|
GPIOBUS *Rascsi_Manager::m_bus;
|
||||||
@@ -17,13 +14,7 @@ DWORD Rascsi_Manager::m_now = 0;
|
|||||||
BOOL Rascsi_Manager::m_active = FALSE;
|
BOOL Rascsi_Manager::m_active = FALSE;
|
||||||
BOOL Rascsi_Manager::m_running = FALSE;
|
BOOL Rascsi_Manager::m_running = FALSE;
|
||||||
std::timed_mutex Rascsi_Manager::m_locked;
|
std::timed_mutex Rascsi_Manager::m_locked;
|
||||||
|
BOOL Rascsi_Manager::m_initialized = FALSE;
|
||||||
Rascsi_Manager* Rascsi_Manager::GetInstance(){
|
|
||||||
if(m_instance != nullptr){
|
|
||||||
m_instance = new Rascsi_Manager();
|
|
||||||
}
|
|
||||||
return m_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL Rascsi_Manager::AttachDevice(FILE *fp, Disk *disk, int id, int unit_num){
|
BOOL Rascsi_Manager::AttachDevice(FILE *fp, Disk *disk, int id, int unit_num){
|
||||||
BOOL result;
|
BOOL result;
|
||||||
@@ -54,7 +45,7 @@ BOOL Rascsi_Manager::AttachDevicePrivate(FILE *fp, Disk *disk, int id, int unit_
|
|||||||
|
|
||||||
// Check if something already exists at that SCSI ID / Unit Number
|
// Check if something already exists at that SCSI ID / Unit Number
|
||||||
if (m_disk[unitno]) {
|
if (m_disk[unitno]) {
|
||||||
DetachDevice(fp,id,unit_num);
|
DetachDevicePrivate(fp,id,unit_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the new unit
|
// Add the new unit
|
||||||
@@ -260,12 +251,11 @@ void Rascsi_Manager::Close(){
|
|||||||
|
|
||||||
BOOL Rascsi_Manager::Init(){
|
BOOL Rascsi_Manager::Init(){
|
||||||
|
|
||||||
if(m_instance != nullptr){
|
if(m_initialized != FALSE){
|
||||||
printf("Can not initialize Rascsi_Manager twice!!!\n");
|
printf("Can not initialize Rascsi_Manager twice!!!\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
m_initialized = TRUE;
|
||||||
m_instance = new Rascsi_Manager();
|
|
||||||
|
|
||||||
// GPIOBUS creation
|
// GPIOBUS creation
|
||||||
m_bus = new GPIOBUS();
|
m_bus = new GPIOBUS();
|
||||||
@@ -288,10 +278,11 @@ BOOL Rascsi_Manager::Init(){
|
|||||||
m_disk[i] = NULL;
|
m_disk[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
|
m_running = TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,3 +396,11 @@ BOOL Rascsi_Manager::Step()
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Rascsi_Manager::Stop(){
|
||||||
|
m_running = FALSE;
|
||||||
|
}
|
||||||
|
BOOL Rascsi_Manager::IsRunning(){
|
||||||
|
return (m_running == TRUE);
|
||||||
|
}
|
||||||
@@ -37,18 +37,20 @@ enum Rascsi_Device_Mode_e{
|
|||||||
class Rascsi_Manager{
|
class Rascsi_Manager{
|
||||||
public:
|
public:
|
||||||
static Rascsi_Manager* GetInstance();
|
static Rascsi_Manager* GetInstance();
|
||||||
void MapControler(FILE *fp, Disk **map);
|
static void MapControler(FILE *fp, Disk **map);
|
||||||
|
|
||||||
|
static void Stop();
|
||||||
|
static BOOL IsRunning();
|
||||||
|
|
||||||
BOOL AttachDevice(FILE *fp, Disk *disk, int id, int ui);
|
static BOOL AttachDevice(FILE *fp, Disk *disk, int id, int ui);
|
||||||
BOOL DetachDevice(FILE *fp, int id, int ui);
|
static BOOL DetachDevice(FILE *fp, int id, int ui);
|
||||||
Disk* GetDevice(FILE *fp, int id, int ui);
|
static Disk* GetDevice(FILE *fp, int id, int ui);
|
||||||
void ListDevice(FILE *fp);
|
static void ListDevice(FILE *fp);
|
||||||
BOOL Init();
|
static BOOL Init();
|
||||||
void Close();
|
static void Close();
|
||||||
void Reset();
|
static void Reset();
|
||||||
BOOL Step();
|
static BOOL Step();
|
||||||
Rascsi_Device_Mode_e GetCurrentDeviceMode();
|
static Rascsi_Device_Mode_e GetCurrentDeviceMode();
|
||||||
|
|
||||||
static const int CtrlMax = 8; // Maximum number of SCSI controllers
|
static const int CtrlMax = 8; // Maximum number of SCSI controllers
|
||||||
static const int UnitNum=2; // Number of units around controller
|
static const int UnitNum=2; // Number of units around controller
|
||||||
@@ -68,12 +70,12 @@ class Rascsi_Manager{
|
|||||||
static BUS::phase_t m_phase;
|
static BUS::phase_t m_phase;
|
||||||
static BYTE m_data;
|
static BYTE m_data;
|
||||||
static DWORD m_now;
|
static DWORD m_now;
|
||||||
static Rascsi_Manager *m_instance;
|
|
||||||
static BOOL m_active;
|
static BOOL m_active;
|
||||||
static BOOL m_running;
|
static BOOL m_running;
|
||||||
|
static BOOL m_initialized;
|
||||||
|
|
||||||
BOOL AttachDevicePrivate(FILE *fp, Disk *disk, int id, int ui);
|
static BOOL AttachDevicePrivate(FILE *fp, Disk *disk, int id, int ui);
|
||||||
BOOL DetachDevicePrivate(FILE *fp, int id, int ui);
|
static BOOL DetachDevicePrivate(FILE *fp, int id, int ui);
|
||||||
|
|
||||||
// Any PUBLIC functions should lock this before accessing the m_ctrl
|
// Any PUBLIC functions should lock this before accessing the m_ctrl
|
||||||
// m_disk or m_bus data structures. The Public functions could be
|
// m_disk or m_bus data structures. The Public functions could be
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// Send Command
|
// Send Command
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
BOOL SendCommand(BYTE *buf)
|
BOOL SendCommand(char *buf)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct sockaddr_in server;
|
struct sockaddr_in server;
|
||||||
@@ -27,7 +27,7 @@ BOOL SendCommand(BYTE *buf)
|
|||||||
fd = socket(PF_INET, SOCK_STREAM, 0);
|
fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
memset(&server, 0, sizeof(server));
|
memset(&server, 0, sizeof(server));
|
||||||
server.sin_family = PF_INET;
|
server.sin_family = PF_INET;
|
||||||
server.sin_port = htons(6868);
|
server.sin_port = htons(Rasctl_Command::PortNumber);
|
||||||
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
|
||||||
// Connect
|
// Connect
|
||||||
@@ -68,16 +68,14 @@ int main(int argc, char* argv[])
|
|||||||
int id;
|
int id;
|
||||||
int un;
|
int un;
|
||||||
char *file;
|
char *file;
|
||||||
int len;
|
char buf[BUFSIZ];
|
||||||
char *ext;
|
|
||||||
BYTE buf[BUFSIZ];
|
|
||||||
rasctl_command cmd = rasctl_cmd_invalid;
|
rasctl_command cmd = rasctl_cmd_invalid;
|
||||||
rasctl_dev_type type = rasctl_dev_invalid;
|
rasctl_dev_type type = rasctl_dev_invalid;
|
||||||
Rasctl_Command *rasctl_cmd;
|
Rasctl_Command *rasctl_cmd;
|
||||||
|
|
||||||
id = -1;
|
id = -1;
|
||||||
un = 0;
|
un = 0;
|
||||||
file = NULL;
|
file = nullptr;
|
||||||
|
|
||||||
// Display help
|
// Display help
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
@@ -102,11 +100,11 @@ int main(int argc, char* argv[])
|
|||||||
while ((opt = getopt(argc, argv, "i:u:c:t:f:l")) != -1) {
|
while ((opt = getopt(argc, argv, "i:u:c:t:f:l")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'i':
|
case 'i':
|
||||||
id = optarg[0] - '0';
|
id = atoi((char*)optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
un = optarg[0] - '0';
|
un = atoi((char*)optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
@@ -175,13 +173,13 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
// Check the ID number
|
// Check the ID number
|
||||||
if (id < 0 || id > 7) {
|
if (id < 0 || id > 7) {
|
||||||
fprintf(stderr, "Error : Invalid ID\n");
|
fprintf(stderr, "Error : Invalid SCSI/SASI ID number %d\n", id);
|
||||||
exit(EINVAL);
|
exit(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the unit number
|
// Check the unit number
|
||||||
if (un < 0 || un > 1) {
|
if (un < 0 || un > 1) {
|
||||||
fprintf(stderr, "Error : Invalid UNIT\n");
|
fprintf(stderr, "Error : Invalid UNIT number %d\n", un);
|
||||||
exit(EINVAL);
|
exit(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,33 +188,10 @@ int main(int argc, char* argv[])
|
|||||||
cmd = rasctl_cmd_attach; // Default command is ATTATCH
|
cmd = rasctl_cmd_attach; // Default command is ATTATCH
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type Check
|
// If the device type is still "invalid" (unknown), try to figure it out
|
||||||
if (cmd == rasctl_cmd_attach && type == rasctl_dev_invalid) {
|
// from the image file name.
|
||||||
|
if (cmd == rasctl_cmd_attach && type == rasctl_dev_invalid && file != nullptr) {
|
||||||
// Try to determine the file type from the extension
|
type = Rasctl_Command::DeviceTypeFromFilename(stderr, file);
|
||||||
len = file ? strlen(file) : 0;
|
|
||||||
if (len > 4 && file[len - 4] == '.') {
|
|
||||||
ext = &file[len - 3];
|
|
||||||
if (xstrcasecmp(ext, "hdf") == 0){
|
|
||||||
type = rasctl_dev_sasi_hd;
|
|
||||||
}else if(xstrcasecmp(ext, "hds") == 0 ||
|
|
||||||
xstrcasecmp(ext, "hdi") == 0 ||
|
|
||||||
xstrcasecmp(ext, "nhd") == 0){
|
|
||||||
type = rasctl_dev_scsi_hd;
|
|
||||||
}else if(xstrcasecmp(ext, "hdn") == 0) {
|
|
||||||
// NEC HD(SASI/SCSI)
|
|
||||||
type = rasctl_dev_scsi_hd_appl;
|
|
||||||
}else if(xstrcasecmp(ext, "hda") == 0) {
|
|
||||||
// Apple HD(SASI/SCSI)
|
|
||||||
type = rasctl_dev_scsi_hd_appl;
|
|
||||||
}else if (xstrcasecmp(ext, "mos") == 0) {
|
|
||||||
// MO
|
|
||||||
type = rasctl_dev_mo;
|
|
||||||
}else if (xstrcasecmp(ext, "iso") == 0) {
|
|
||||||
// CD
|
|
||||||
type = rasctl_dev_cd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == rasctl_dev_invalid) {
|
if (type == rasctl_dev_invalid) {
|
||||||
fprintf(stderr, "Error : Invalid type\n");
|
fprintf(stderr, "Error : Invalid type\n");
|
||||||
@@ -255,12 +230,14 @@ int main(int argc, char* argv[])
|
|||||||
strncpy(rasctl_cmd->file,file,_MAX_PATH);
|
strncpy(rasctl_cmd->file,file,_MAX_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(rasctl_cmd->IsValid(stderr)){
|
||||||
// Generate the command and send it
|
// Generate the command and send it
|
||||||
rasctl_cmd->Serialize(buf,BUFSIZ);
|
rasctl_cmd->Serialize(buf,BUFSIZ);
|
||||||
|
|
||||||
if (!SendCommand(buf)) {
|
if (!SendCommand(buf)) {
|
||||||
exit(ENOTCONN);
|
exit(ENOTCONN);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// All done!
|
// All done!
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|||||||
@@ -1,23 +1,41 @@
|
|||||||
#include "rasctl_command.h"
|
#include "rasctl_command.h"
|
||||||
#include "rascsi_mgr.h"
|
#include "rascsi_mgr.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
const char* Rasctl_Command::m_delimiter = "\x1E"; // Record separator charater
|
// In the serialized string from rasctl
|
||||||
//const char* Rasctl_Command::m_delimiter = " "; // Record separator charater
|
const char* Rasctl_Command::m_delimiter = "\x1E\n"; // Record separator charater
|
||||||
|
const char* Rasctl_Command::m_no_file = "----";
|
||||||
|
const uint16_t Rasctl_Command::PortNumber = 6868;
|
||||||
|
|
||||||
void Rasctl_Command::Serialize(BYTE *buff, int max_buff_size){
|
const char* Rasctl_Command::dev_type_lookup[] = {
|
||||||
snprintf((char*)buff, max_buff_size, "%d%s%d%s%d%s%d%s%s%s\n",
|
"SASI Hard Drive", // rasctl_dev_sasi_hd = 0,
|
||||||
this->id, this->m_delimiter,
|
"SCSI Hard Drive", // rasctl_dev_scsi_hd = 1,
|
||||||
this->un, this->m_delimiter,
|
"Magneto Optical Drive", // rasctl_dev_mo = 2,
|
||||||
this->cmd, this->m_delimiter,
|
"CD-ROM", // rasctl_dev_cd = 3,
|
||||||
this->type, this->m_delimiter,
|
"Host Bridge", // rasctl_dev_br = 4,
|
||||||
this->file, this->m_delimiter);
|
"Apple SCSI Hard Drive", // rasctl_dev_scsi_hd_appl = 5,
|
||||||
|
"NEC SCSI Hard DRive", // rasctl_dev_scsi_hd_nec = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
void Rasctl_Command::Serialize(char *buff, int max_buff_size){
|
||||||
|
// The filename string can't be empty. Otherwise, strtok will
|
||||||
|
// ignore the field on the receiving end.
|
||||||
|
if(strlen(this->file) < 1){
|
||||||
|
strcpy(this->file,m_no_file);
|
||||||
|
}
|
||||||
|
snprintf(buff, max_buff_size, "%d%c%d%c%d%c%d%c%s%c\n",
|
||||||
|
this->id, this->m_delimiter[0],
|
||||||
|
this->un, this->m_delimiter[0],
|
||||||
|
this->cmd, this->m_delimiter[0],
|
||||||
|
this->type, this->m_delimiter[0],
|
||||||
|
this->file, this->m_delimiter[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rasctl_Command* Rasctl_Command::DeSerialize(BYTE* buff, int size){
|
Rasctl_Command* Rasctl_Command::DeSerialize(char* buff, int size){
|
||||||
Rasctl_Command *return_command = new Rasctl_Command();
|
Rasctl_Command *return_command = new Rasctl_Command();
|
||||||
char err_message[256];
|
char err_message[256];
|
||||||
char *cur_token;
|
char *cur_token;
|
||||||
char *command = (char*)buff;
|
char *command = buff;
|
||||||
serial_token_order cur_token_idx = serial_token_first_token;
|
serial_token_order cur_token_idx = serial_token_first_token;
|
||||||
|
|
||||||
cur_token = strtok(command, m_delimiter);
|
cur_token = strtok(command, m_delimiter);
|
||||||
@@ -31,7 +49,11 @@ Rasctl_Command* Rasctl_Command::DeSerialize(BYTE* buff, int size){
|
|||||||
return_command->type = (rasctl_dev_type)atoi(cur_token);
|
return_command->type = (rasctl_dev_type)atoi(cur_token);
|
||||||
break;
|
break;
|
||||||
case serial_token_file_name:
|
case serial_token_file_name:
|
||||||
|
if(strncmp(cur_token,m_no_file,strlen(m_no_file)) != 0){
|
||||||
strncpy(return_command->file,cur_token,_MAX_PATH);
|
strncpy(return_command->file,cur_token,_MAX_PATH);
|
||||||
|
} else {
|
||||||
|
strncpy(return_command->file,"",_MAX_PATH);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case serial_token_id:
|
case serial_token_id:
|
||||||
return_command->id = atoi(cur_token);
|
return_command->id = atoi(cur_token);
|
||||||
@@ -78,6 +100,7 @@ BOOL Rasctl_Command::rasctl_dev_is_hd(rasctl_dev_type type)
|
|||||||
|
|
||||||
BOOL Rasctl_Command::IsValid(FILE *fp){
|
BOOL Rasctl_Command::IsValid(FILE *fp){
|
||||||
struct stat stat_buffer;
|
struct stat stat_buffer;
|
||||||
|
rasctl_dev_type expected_type = rasctl_dev_invalid;
|
||||||
|
|
||||||
// If the command is "invalid" we can just return FALSE
|
// If the command is "invalid" we can just return FALSE
|
||||||
if(cmd == rasctl_cmd_invalid){
|
if(cmd == rasctl_cmd_invalid){
|
||||||
@@ -117,7 +140,7 @@ BOOL Rasctl_Command::IsValid(FILE *fp){
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
// Check that the file exists if specified
|
// Check that the file exists if specified
|
||||||
if(stat(file, &stat_buffer) == 0){
|
if(stat(file, &stat_buffer) != 0){
|
||||||
FPRT(fp, "File %s is not accessible", file);
|
FPRT(fp, "File %s is not accessible", file);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -128,74 +151,49 @@ BOOL Rasctl_Command::IsValid(FILE *fp){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// char* path = optarg;
|
// Check if the filename extension matches the device type
|
||||||
// int type = -1;
|
expected_type = DeviceTypeFromFilename(fp, file);
|
||||||
// if (HasSuffix(path, ".hdf")
|
if(expected_type != rasctl_dev_invalid){
|
||||||
// || HasSuffix(path, ".hds")
|
if((file != nullptr) && (type != expected_type)) {
|
||||||
// || HasSuffix(path, ".hdn")
|
FPRT(fp, "Filename specified is for type %s. This isn't compatible with a %s device.",
|
||||||
// || HasSuffix(path, ".hdi")
|
dev_type_lookup[expected_type], dev_type_lookup[type]);
|
||||||
// || HasSuffix(path, ".hda")
|
return FALSE;
|
||||||
// || HasSuffix(path, ".nhd")) {
|
}
|
||||||
// type = 0;
|
}
|
||||||
// } else if (HasSuffix(path, ".mos")) {
|
|
||||||
// type = 2;
|
|
||||||
// } else if (HasSuffix(path, ".iso")) {
|
|
||||||
// type = 3;
|
|
||||||
// } else if (xstrcasecmp(path, "bridge") == 0) {
|
|
||||||
// type = 4;
|
|
||||||
// } else {
|
|
||||||
// // Cannot determine the file type
|
|
||||||
// fprintf(stderr,
|
|
||||||
// "%s: unknown file extension\n", path);
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// int un = 0;
|
|
||||||
// if (is_sasi) {
|
|
||||||
// un = id % Rascsi_Manager::UnitNum;
|
|
||||||
// id /= Rascsi_Manager::UnitNum;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Execute the command
|
|
||||||
// if (!ExecuteCommand(stderr, id, un, 0, type, path)) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// id = -1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Display the device list
|
|
||||||
// Rascsi_Manager::GetInstance()->ListDevice(stdout);
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// if (type == 0) {
|
|
||||||
// // Passed the check
|
|
||||||
// if (!file) {
|
|
||||||
// return FALSE;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Check that command is at least 5 characters long
|
|
||||||
// len = strlen(file);
|
|
||||||
// if (len < 5) {
|
|
||||||
// return FALSE;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Check the extension
|
|
||||||
// if (file[len - 4] != '.') {
|
|
||||||
// return FALSE;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // If the extension is not SASI type, replace with SCSI
|
|
||||||
// ext = &file[len - 3];
|
|
||||||
// if (xstrcasecmp(ext, "hdf") != 0) {
|
|
||||||
// type = 1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
|
// Everything appears to be OK
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rasctl_dev_type Rasctl_Command::DeviceTypeFromFilename(FILE *fp, const char* filename){
|
||||||
|
|
||||||
|
const char *extension = strrchr(filename,'.');
|
||||||
|
rasctl_dev_type ret_type = rasctl_dev_invalid;
|
||||||
|
|
||||||
|
if(extension == nullptr){
|
||||||
|
fprintf(fp, "Missing file extension from %s",filename);
|
||||||
|
return rasctl_dev_invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strcasecmp(extension,".hdf") == 0){
|
||||||
|
ret_type = rasctl_dev_sasi_hd;
|
||||||
|
}else if((strcasecmp(extension,".hds") == 0) ||
|
||||||
|
(strcasecmp(extension,".hdi") == 0) ||
|
||||||
|
(strcasecmp(extension,".nhd") == 0)){
|
||||||
|
ret_type = rasctl_dev_scsi_hd;
|
||||||
|
}else if(strcasecmp(extension,".hdn") == 0){
|
||||||
|
ret_type = rasctl_dev_scsi_hd_nec;
|
||||||
|
}else if(strcasecmp(extension,".hdi") == 0){
|
||||||
|
ret_type = rasctl_dev_scsi_hd_nec;
|
||||||
|
}else if(strcasecmp(extension,".hda") == 0){
|
||||||
|
ret_type = rasctl_dev_scsi_hd_appl;
|
||||||
|
}else if(strcasecmp(extension,".mos") == 0){
|
||||||
|
ret_type = rasctl_dev_mo;
|
||||||
|
}else if(strcasecmp(extension,".iso") == 0){
|
||||||
|
ret_type = rasctl_dev_cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ enum rasctl_dev_type : int {
|
|||||||
|
|
||||||
class Rasctl_Command{
|
class Rasctl_Command{
|
||||||
public:
|
public:
|
||||||
void Serialize(BYTE *buff, int max_buff_size);
|
void Serialize(char *buff, int max_buff_size);
|
||||||
static Rasctl_Command* DeSerialize(BYTE* buff, int size);
|
static Rasctl_Command* DeSerialize(char* buff, int size);
|
||||||
BOOL IsValid(FILE *fp);
|
BOOL IsValid(FILE *fp);
|
||||||
|
|
||||||
|
|
||||||
@@ -49,12 +49,17 @@ class Rasctl_Command{
|
|||||||
rasctl_dev_type type = rasctl_dev_invalid;
|
rasctl_dev_type type = rasctl_dev_invalid;
|
||||||
int id = -1;
|
int id = -1;
|
||||||
int un = -1;
|
int un = -1;
|
||||||
char file[_MAX_PATH];
|
char file[_MAX_PATH] = "";
|
||||||
|
|
||||||
static BOOL rasctl_dev_is_hd(rasctl_dev_type dev);
|
static BOOL rasctl_dev_is_hd(rasctl_dev_type dev);
|
||||||
|
static const uint16_t PortNumber;
|
||||||
|
|
||||||
|
static rasctl_dev_type DeviceTypeFromFilename(FILE *fp, const char* filename);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char* m_delimiter; // Record separator charater
|
static const char* m_delimiter; // Record separator charater
|
||||||
|
static const char* m_no_file; // Special character sequence indicating an empty file name.
|
||||||
|
|
||||||
|
|
||||||
enum serial_token_order : int {
|
enum serial_token_order : int {
|
||||||
serial_token_first_token = 0,
|
serial_token_first_token = 0,
|
||||||
@@ -65,4 +70,6 @@ class Rasctl_Command{
|
|||||||
serial_token_file_name = 4,
|
serial_token_file_name = 4,
|
||||||
serial_token_last_token = 5,
|
serial_token_last_token = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char* dev_type_lookup[];
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user