From acd3cb27221bdebd290521f2159eed38f65e6cb6 Mon Sep 17 00:00:00 2001 From: akuker <34318535+akuker@users.noreply.github.com> Date: Sun, 24 Jan 2021 21:45:53 -0600 Subject: [PATCH 01/22] Update README.md Added reference to gitflow --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 5635a4f3..5652d747 100644 --- a/README.md +++ b/README.md @@ -9,4 +9,14 @@ RaSCSI is a virtual SCSI device emulator that runs on a Raspberry Pi. It runs in Please check out the full story with much more detail on the [wiki](https://github.com/akuker/RASCSI/wiki)! +# How do I contribute? +RaSCSI is using the Gitflow Workflow. A quick overview: + +- The *master* branch should always reflect the contents of the last stable release +- The *develop* branch should contain the latest tested & approved updates. Pull requests should be used to merge changes into develop. +- The rest of the feature branches are for developing new features +- A tag will be created for each "release". The releases will be named . (for the first release of the month). Hot fixes, if necessary, will be released as ... For example, the first release in January 2021 will be release "21.01". If a hot-fix is needed for this release, the first hotfix will be "21.01.1". + +Typically, releases will only be planned every few months. + I sell on Tindie From 96673a44b056f0518ef2c9baa93dc614e8720927 Mon Sep 17 00:00:00 2001 From: akuker <34318535+akuker@users.noreply.github.com> Date: Mon, 25 Jan 2021 10:07:30 -0600 Subject: [PATCH 02/22] Updated to match new versioning structure (#73) * Updated to match new versioning structure * fix version number Co-authored-by: Tony Kuker --- src/raspberrypi/Makefile | 13 ++++-- src/raspberrypi/controllers/scsidev_ctrl.cpp | 9 ++-- src/raspberrypi/rascsi.cpp | 7 ++-- src/raspberrypi/rascsi_version.cpp | 44 ++++++++++++++++++++ src/raspberrypi/rascsi_version.h | 21 ++++++++++ src/raspberrypi/rasctl.cpp | 5 +++ src/raspberrypi/rasdump.cpp | 9 ++-- src/raspberrypi/sasidump.cpp | 9 ++-- src/raspberrypi/scsimon.cpp | 7 ++-- src/raspberrypi/xm6.h | 9 +--- 10 files changed, 99 insertions(+), 34 deletions(-) create mode 100644 src/raspberrypi/rascsi_version.cpp create mode 100644 src/raspberrypi/rascsi_version.h diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 0460be00..34d421a4 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -75,6 +75,7 @@ SRC_RASCSI = \ gpiobus.cpp \ filepath.cpp \ fileio.cpp\ + rascsi_version.cpp # os.cpp # rasctl_command.cpp # rascsi_mgr.cpp @@ -87,13 +88,15 @@ SRC_SCSIMON = \ scsi.cpp \ gpiobus.cpp \ filepath.cpp \ - fileio.cpp + fileio.cpp\ + rascsi_version.cpp SRC_SCSIMON += $(shell find ./controllers -name '*.cpp') SRC_SCSIMON += $(shell find ./devices -name '*.cpp') SRC_RASCTL = \ - rasctl.cpp + rasctl.cpp\ + rascsi_version.cpp # rasctl_command.cpp SRC_RASDUMP = \ @@ -101,14 +104,16 @@ SRC_RASDUMP = \ scsi.cpp \ gpiobus.cpp \ filepath.cpp \ - fileio.cpp + fileio.cpp\ + rascsi_version.cpp SRC_SASIDUMP = \ sasidump.cpp \ scsi.cpp \ gpiobus.cpp \ filepath.cpp \ - fileio.cpp + fileio.cpp\ + rascsi_version.cpp vpath %.h ./ ./controllers ./devices vpath %.cpp ./ ./controllers ./devices diff --git a/src/raspberrypi/controllers/scsidev_ctrl.cpp b/src/raspberrypi/controllers/scsidev_ctrl.cpp index db237096..a496eeb4 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.cpp +++ b/src/raspberrypi/controllers/scsidev_ctrl.cpp @@ -16,6 +16,7 @@ #include "controllers/scsidev_ctrl.h" #include "gpiobus.h" #include "devices/scsi_host_bridge.h" +#include "rascsi_version.h" //=========================================================================== // @@ -553,12 +554,8 @@ void FASTCALL SCSIDEV::CmdInquiry() // Processed on the disk side (it is originally processed by the controller) if (disk) { -#ifdef RASCSI - major = (DWORD)(RASCSI >> 8); - minor = (DWORD)(RASCSI & 0xff); -#else - host->GetVM()->GetVersion(major, minor); -#endif // RASCSI + major = (DWORD)rascsi_major_version; + minor = (DWORD)rascsi_minor_version; ctrl.length = ctrl.unit[lun]->Inquiry(ctrl.cmd, ctrl.buffer, major, minor); } else { diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index baf6c34a..8fc44ae1 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -24,6 +24,7 @@ #include "controllers/scsidev_ctrl.h" #include "controllers/sasidev_ctrl.h" #include "gpiobus.h" +#include "rascsi_version.h" #include "spdlog/spdlog.h" //--------------------------------------------------------------------------- @@ -78,10 +79,8 @@ void KillHandler(int sig) void Banner(int argc, char* argv[]) { FPRT(stdout,"SCSI Target Emulator RaSCSI(*^..^*) "); - FPRT(stdout,"version %01d.%01d%01d(%s, %s)\n", - (int)((VERSION >> 8) & 0xf), - (int)((VERSION >> 4) & 0xf), - (int)((VERSION ) & 0xf), + FPRT(stdout,"version %s (%s, %s)\n", + rascsi_get_version_string(), __DATE__, __TIME__); FPRT(stdout,"Powered by XM6 TypeG Technology / "); diff --git a/src/raspberrypi/rascsi_version.cpp b/src/raspberrypi/rascsi_version.cpp new file mode 100644 index 00000000..ee099f06 --- /dev/null +++ b/src/raspberrypi/rascsi_version.cpp @@ -0,0 +1,44 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI (*^..^*) +// for Raspberry Pi +// +// Copyright (C) 2020 akuker +// [ Define the version string] +// +//--------------------------------------------------------------------------- + +#include "rascsi_version.h" +#include +#include + +// The following should be updated for each release +const int rascsi_major_version = 20; // Last two digits of year +const int rascsi_minor_version = 12; // Month +const int rascsi_patch_version = 0; // Patch number - increment for each update + +static char rascsi_version_string[30]; // Allow for string up to "XX.XX.XXX" + null character + "development build" + +//--------------------------------------------------------------------------- +// +// Get the RaSCSI version string +// +//--------------------------------------------------------------------------- +char* rascsi_get_version_string() +{ + if(rascsi_patch_version < 0) + { + snprintf(rascsi_version_string, sizeof(rascsi_version_string), + "%02d.%02d --DEVELOPMENT BUILD--", + rascsi_major_version, + rascsi_minor_version); + } + else + { + snprintf(rascsi_version_string, sizeof(rascsi_version_string), "%02d.%02d.%d", + rascsi_major_version, + rascsi_minor_version, + rascsi_patch_version); + } + return rascsi_version_string; +} diff --git a/src/raspberrypi/rascsi_version.h b/src/raspberrypi/rascsi_version.h new file mode 100644 index 00000000..17a2d345 --- /dev/null +++ b/src/raspberrypi/rascsi_version.h @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI (*^..^*) +// for Raspberry Pi +// +// Copyright (C) 2020 akuker +// [ Define the version string] +// +//--------------------------------------------------------------------------- +#pragma once + +extern const int rascsi_major_version; // Last two digits of year +extern const int rascsi_minor_version; // Month +extern const int rascsi_patch_version; // Patch number + +//--------------------------------------------------------------------------- +// +// Fetch the version string +// +//--------------------------------------------------------------------------- +extern char* rascsi_get_version_string(); diff --git a/src/raspberrypi/rasctl.cpp b/src/raspberrypi/rasctl.cpp index 9141c237..c99e5d01 100644 --- a/src/raspberrypi/rasctl.cpp +++ b/src/raspberrypi/rasctl.cpp @@ -10,6 +10,7 @@ //--------------------------------------------------------------------------- #include "os.h" +#include "rascsi_version.h" //--------------------------------------------------------------------------- // @@ -84,6 +85,10 @@ int main(int argc, char* argv[]) // Display help if (argc < 2) { fprintf(stderr, "SCSI Target Emulator RaSCSI Controller\n"); + fprintf(stderr, "version %s (%s, %s)\n", + rascsi_get_version_string(), + __DATE__, + __TIME__); fprintf(stderr, "Usage: %s -i ID [-u UNIT] [-c CMD] [-t TYPE] [-f FILE]\n", argv[0]); diff --git a/src/raspberrypi/rasdump.cpp b/src/raspberrypi/rasdump.cpp index bf199545..776103dc 100644 --- a/src/raspberrypi/rasdump.cpp +++ b/src/raspberrypi/rasdump.cpp @@ -14,6 +14,7 @@ #include "fileio.h" #include "filepath.h" #include "gpiobus.h" +#include "rascsi_version.h" //--------------------------------------------------------------------------- // @@ -62,10 +63,10 @@ void KillHandler(int sig) BOOL Banner(int argc, char* argv[]) { printf("RaSCSI hard disk dump utility "); - printf("version %01d.%01d%01d\n", - (int)((VERSION >> 8) & 0xf), - (int)((VERSION >> 4) & 0xf), - (int)((VERSION ) & 0xf)); + printf("version %s (%s, %s)\n", + rascsi_get_version_string(), + __DATE__, + __TIME__); if (argc < 2 || strcmp(argv[1], "-h") == 0) { printf("Usage: %s -i ID [-b BID] -f FILE [-r]\n", argv[0]); diff --git a/src/raspberrypi/sasidump.cpp b/src/raspberrypi/sasidump.cpp index 4a7b9724..3e9dc960 100644 --- a/src/raspberrypi/sasidump.cpp +++ b/src/raspberrypi/sasidump.cpp @@ -23,6 +23,7 @@ #include "fileio.h" #include "filepath.h" #include "gpiobus.h" +#include "rascsi_version.h" //--------------------------------------------------------------------------- // @@ -73,10 +74,10 @@ void KillHandler(int sig) BOOL Banner(int argc, char* argv[]) { printf("RaSCSI hard disk dump utility(SASI HDD) "); - printf("version %01d.%01d%01d\n", - (int)((VERSION >> 8) & 0xf), - (int)((VERSION >> 4) & 0xf), - (int)((VERSION ) & 0xf)); + printf("version %s (%s, %s)\n", + rascsi_get_version_string(), + __DATE__, + __TIME__); if (argc < 2 || strcmp(argv[1], "-h") == 0) { printf("Usage: %s -i ID [-u UT] [-b BSIZE] -c COUNT -f FILE [-r]\n", argv[0]); diff --git a/src/raspberrypi/scsimon.cpp b/src/raspberrypi/scsimon.cpp index 1f551d24..d794a7c9 100644 --- a/src/raspberrypi/scsimon.cpp +++ b/src/raspberrypi/scsimon.cpp @@ -16,6 +16,7 @@ #include "devices/disk.h" #include "log.h" #include "gpiobus.h" +#include "rascsi_version.h" #include "spdlog/spdlog.h" #include @@ -80,10 +81,8 @@ void KillHandler(int sig) void Banner(int argc, char* argv[]) { LOGINFO("SCSI Monitor Capture Tool - part of RaSCSI(*^..^*) "); - LOGINFO("version %01d.%01d%01d(%s, %s)", - (int)((VERSION >> 8) & 0xf), - (int)((VERSION >> 4) & 0xf), - (int)((VERSION ) & 0xf), + LOGINFO("version %s (%s, %s)\n", + rascsi_get_version_string(), __DATE__, __TIME__); LOGINFO("Powered by XM6 TypeG Technology "); diff --git a/src/raspberrypi/xm6.h b/src/raspberrypi/xm6.h index a349b788..1d0fc943 100644 --- a/src/raspberrypi/xm6.h +++ b/src/raspberrypi/xm6.h @@ -13,19 +13,12 @@ #if !defined(xm6_h) #define xm6_h -//--------------------------------------------------------------------------- -// -// VERSION -// -//--------------------------------------------------------------------------- -#define VERSION 0x0147 - //--------------------------------------------------------------------------- // // RaSCSI // //--------------------------------------------------------------------------- -#define RASCSI VERSION +#define RASCSI 1 //--------------------------------------------------------------------------- // From 350010462c72cfb7a0ea7880cab632dbe90e61d9 Mon Sep 17 00:00:00 2001 From: akuker <34318535+akuker@users.noreply.github.com> Date: Mon, 25 Jan 2021 10:07:49 -0600 Subject: [PATCH 03/22] Scsimon improvements (#74) * Updated scsimon to save data on a nano-second time scale, instead of micro-second * Cleanup error messages and data types Co-authored-by: Tony Kuker --- src/raspberrypi/os.h | 1 + src/raspberrypi/scsimon.cpp | 130 +++++++++++++++++++++++++++--------- 2 files changed, 99 insertions(+), 32 deletions(-) diff --git a/src/raspberrypi/os.h b/src/raspberrypi/os.h index e744559f..e1da949e 100644 --- a/src/raspberrypi/os.h +++ b/src/raspberrypi/os.h @@ -124,6 +124,7 @@ typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; +typedef unsigned long long QWORD; typedef int BOOL; typedef char TCHAR; typedef char *LPTSTR; diff --git a/src/raspberrypi/scsimon.cpp b/src/raspberrypi/scsimon.cpp index d794a7c9..8a2f9450 100644 --- a/src/raspberrypi/scsimon.cpp +++ b/src/raspberrypi/scsimon.cpp @@ -56,11 +56,18 @@ static volatile BOOL active; // Processing flag GPIOBUS *bus; // GPIO Bus typedef struct data_capture{ DWORD data; - timeval timestamp; + QWORD timestamp; } data_capture_t; data_capture data_buffer[MAX_BUFF_SIZE]; -int data_idx = 0; +DWORD data_idx = 0; + +double ns_per_loop; + +// We don't really need to support 256 character file names - this causes +// all kinds of compiler warnings when the log filename can be up to 256 +// characters. _MAX_FNAME/2 is just an arbitrary value. +char log_file_name[_MAX_FNAME/2] = "log.vcd"; //--------------------------------------------------------------------------- // @@ -89,17 +96,17 @@ void Banner(int argc, char* argv[]) LOGINFO("Copyright (C) 2016-2020 GIMONS"); LOGINFO("Copyright (C) 2020 akuker"); LOGINFO("Connect type : %s", CONNECT_DESC); - LOGINFO(" log.vcd - Value Change Dump file that can be opened with GTKWave"); + LOGINFO(" %s - Value Change Dump file that can be opened with GTKWave", log_file_name); if ((argc > 1 && strcmp(argv[1], "-h") == 0) || (argc > 1 && strcmp(argv[1], "--help") == 0)){ - LOGINFO("Usage: %s ...", argv[0]); + LOGINFO("Usage: %s [log filename]...", argv[0]); exit(0); } else { LOGINFO(" "); - LOGINFO("Current running & collecting data. Press CTRL-C to stop.") + LOGINFO("Now collecting data.... Press CTRL-C to stop.") LOGINFO(" "); } } @@ -150,14 +157,14 @@ BYTE get_data_field(DWORD data) { DWORD data_out; data_out = - ((data >> (PIN_DT0 - 0)) & (1 << 0)) | - ((data >> (PIN_DT1 - 1)) & (1 << 1)) | - ((data >> (PIN_DT2 - 2)) & (1 << 2)) | - ((data >> (PIN_DT3 - 3)) & (1 << 3)) | - ((data >> (PIN_DT4 - 4)) & (1 << 4)) | - ((data >> (PIN_DT5 - 5)) & (1 << 5)) | - ((data >> (PIN_DT6 - 6)) & (1 << 6)) | - ((data >> (PIN_DT7 - 7)) & (1 << 7)); + ((data >> (PIN_DT0 - 0)) & (1 << 7)) | + ((data >> (PIN_DT1 - 1)) & (1 << 6)) | + ((data >> (PIN_DT2 - 2)) & (1 << 5)) | + ((data >> (PIN_DT3 - 3)) & (1 << 4)) | + ((data >> (PIN_DT4 - 4)) & (1 << 3)) | + ((data >> (PIN_DT5 - 5)) & (1 << 2)) | + ((data >> (PIN_DT6 - 6)) & (1 << 1)) | + ((data >> (PIN_DT7 - 7)) & (1 << 0)); return (BYTE)data_out; } @@ -189,14 +196,14 @@ void vcd_output_if_changed_byte(FILE *fp, DWORD data, int pin, char symbol) { prev_value[pin] = new_value; fprintf(fp, "b%d%d%d%d%d%d%d%d %c\n", - get_pin_value(data,PIN_DT0), - get_pin_value(data,PIN_DT1), - get_pin_value(data,PIN_DT2), - get_pin_value(data,PIN_DT3), - get_pin_value(data,PIN_DT4), - get_pin_value(data,PIN_DT5), + get_pin_value(data,PIN_DT7), get_pin_value(data,PIN_DT6), - get_pin_value(data,PIN_DT7), symbol); + get_pin_value(data,PIN_DT5), + get_pin_value(data,PIN_DT4), + get_pin_value(data,PIN_DT3), + get_pin_value(data,PIN_DT2), + get_pin_value(data,PIN_DT1), + get_pin_value(data,PIN_DT0), symbol); } } @@ -206,13 +213,11 @@ void create_value_change_dump() { time_t rawtime; struct tm * timeinfo; - int i = 0; - timeval time_diff; + DWORD i = 0; char timestamp[256]; FILE *fp; - timeval start_time = data_buffer[0].timestamp; - LOGINFO("Creating Value Change Dump file (log.vcd)\n"); - fp = fopen("log.vcd","w"); + LOGINFO("Creating Value Change Dump file (%s)", log_file_name); + fp = fopen(log_file_name,"w"); // Get the current time time (&rawtime); @@ -226,9 +231,9 @@ void create_value_change_dump() fprintf(fp, " VCD generator tool version info text.\n"); fprintf(fp, "$end\n"); fprintf(fp, "$comment\n"); - fprintf(fp, " Any comment text.\n"); + fprintf(fp, " Tool build date:%s\n", __TIMESTAMP__); fprintf(fp, "$end\n"); - fprintf(fp, "$timescale 1 us $end\n"); + fprintf(fp, "$timescale 1 ns $end\n"); fprintf(fp, "$scope module logic $end\n"); fprintf(fp, "$var wire 1 %c BSY $end\n", SYMBOL_PIN_BSY); fprintf(fp, "$var wire 1 %c SEL $end\n", SYMBOL_PIN_SEL); @@ -260,8 +265,7 @@ void create_value_change_dump() while(i < data_idx) { - timersub(&(data_buffer[i].timestamp), &start_time, &time_diff); - fprintf(fp, "#%ld\n",((time_diff.tv_sec*1000000) + time_diff.tv_usec)); + fprintf(fp, "#%llu\n",(QWORD)(data_buffer[i].timestamp*ns_per_loop)); vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_BSY, SYMBOL_PIN_BSY); vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_SEL, SYMBOL_PIN_SEL); vcd_output_if_changed_bool(fp, data_buffer[i].data, PIN_CD, SYMBOL_PIN_CD); @@ -288,7 +292,7 @@ void create_value_change_dump() void Cleanup() { - LOGINFO("Stoping data collection....\n"); + LOGINFO("Stopping data collection...."); create_value_change_dump(); // Cleanup the Bus @@ -353,8 +357,34 @@ int main(int argc, char* argv[]) DWORD this_sample = 0; int ret; struct sched_param schparam; + timeval start_time, stop_time; + QWORD loop_count = 0; + timeval time_diff; + QWORD elapsed_us; + int str_len; + // If there is an argument specified and it is NOT -h or --help + if((argc > 1) && (strcmp(argv[1], "-h")) && (strcmp(argv[1], "--help"))){ + str_len = strlen(argv[1]); + if ((str_len >= 1) && (str_len < _MAX_FNAME)) + { + strncpy(log_file_name, argv[1], sizeof(log_file_name)); + // Append .vcd if its not already there + if((str_len < 4) || strcasecmp(log_file_name + (str_len - 4), ".vcd")) { + strcat(log_file_name, ".vcd"); + } + } + else + { + printf("Invalid log name specified. Using log.vcd"); + } + } + +#ifdef DEBUG spdlog::set_level(spdlog::level::trace); +#else + spdlog::set_level(spdlog::level::info); +#endif spdlog::set_pattern("%^[%l]%$ %v"); // Output the Banner Banner(argc, argv); @@ -381,11 +411,24 @@ int main(int argc, char* argv[]) running = TRUE; bus->SetACT(FALSE); + (void)gettimeofday(&start_time, NULL); + LOGDEBUG("ALL_SCSI_PINS %08X\n",ALL_SCSI_PINS); // Main Loop while (running) { // Work initialization this_sample = (bus->Aquire() & ALL_SCSI_PINS); + loop_count++; + if(loop_count > LLONG_MAX -1) + { + LOGINFO("Maximum amount of time has elapsed. SCSIMON is terminating."); + running=false; + } + if(data_idx >= (MAX_BUFF_SIZE-2)) + { + LOGINFO("Internal data buffer is full. SCSIMON is terminating."); + running=false; + } if(this_sample != prev_sample) { @@ -401,16 +444,39 @@ int main(int argc, char* argv[]) } prev_high = high_bits; prev_low = low_bits; + if((data_idx % 1000) == 0){ + LOGDEBUG("Collected %lu samples...", data_idx); + } #endif data_buffer[data_idx].data = this_sample; - (void)gettimeofday(&(data_buffer[data_idx].timestamp), NULL); - data_idx = (data_idx + 1) % MAX_BUFF_SIZE; + data_buffer[data_idx].timestamp = loop_count; + data_idx++; prev_sample = this_sample; } continue; } + // Collect one last sample, otherwise it looks like the end of the data was cut off + if(data_idx < MAX_BUFF_SIZE) + { + data_buffer[data_idx].data = this_sample; + data_buffer[data_idx].timestamp = loop_count; + data_idx++; + } + + (void)gettimeofday(&stop_time, NULL); + + timersub(&stop_time, &start_time, &time_diff); + + elapsed_us = ((time_diff.tv_sec*1000000) + time_diff.tv_usec); + LOGINFO("Elapsed time: %llu microseconds (%lf seconds)",elapsed_us, ((double)elapsed_us)/1000000); + LOGINFO("Collected %lu changes", data_idx); + + // Note: ns_per_loop is a global variable that is used by Cleanup() to printout the timestamps. + ns_per_loop = (elapsed_us * 1000) / (double)loop_count; + LOGINFO("Read the SCSI bus %llu times with an average of %lu ns for each read", loop_count, (DWORD)ns_per_loop); + // Cleanup Cleanup(); From 44ce6c96c037e1ebc0fb26d7f7147c476a0b6866 Mon Sep 17 00:00:00 2001 From: akuker Date: Mon, 25 Jan 2021 13:15:29 -0600 Subject: [PATCH 04/22] Updated for new version number --- test/robot/rascsi_device_information.robot | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/robot/rascsi_device_information.robot b/test/robot/rascsi_device_information.robot index c5673842..c76908dd 100644 --- a/test/robot/rascsi_device_information.robot +++ b/test/robot/rascsi_device_information.robot @@ -27,7 +27,7 @@ Apple Hard Drive reports the correct device information Then Rasctl reports SCSI ID 0 of type HD And SCSI ID 0 is detected by Linux And SCSI ID 0 reports vendor ${SPACE}SEAGATE - And SCSI ID 0 reports revision 0147 + And SCSI ID 0 reports revision 0200 And SCSI ID 0 reports model ${SPACE*10}ST225N And SCSI ID 0 reports type ${Scsi_device_type_hard_drive} @@ -40,7 +40,7 @@ XM6 Hard Drive reports the correct device information Then Rasctl reports SCSI ID 1 of type HD And SCSI ID 1 is detected by Linux And SCSI ID 1 reports vendor RaSCSI${SPACE*2} - And SCSI ID 1 reports revision 0147 + And SCSI ID 1 reports revision 0200 And SCSI ID 1 reports model PRODRIVE LPS10S${SPACE} And SCSI ID 1 reports type ${Scsi_device_type_hard_drive} @@ -53,7 +53,7 @@ NEC Hard Drive reports the correct device information Then Rasctl reports SCSI ID 2 of type HD And SCSI ID 2 is detected by Linux And SCSI ID 2 reports vendor NECCSI${SPACE*2} - And SCSI ID 2 reports revision 0147 + And SCSI ID 2 reports revision 0200 And SCSI ID 2 reports model PRODRIVE LPS10S${SPACE} And SCSI ID 2 reports type ${Scsi_device_type_hard_drive} @@ -66,7 +66,7 @@ Anex86 Hard Drive reports the correct device information Then Rasctl reports SCSI ID 3 of type HD And SCSI ID 3 is detected by Linux And SCSI ID 3 reports vendor RaSCSI${SPACE*2} - And SCSI ID 3 reports revision 0147 + And SCSI ID 3 reports revision 0200 And SCSI ID 3 reports model CD-ROM CDU-55S${SPACE*2} And SCSI ID 3 reports type ${Scsi_device_type_hard_drive} @@ -77,7 +77,7 @@ CD-ROM drive reports the correct device information Then Rasctl reports SCSI ID 4 of type CD And SCSI ID 4 is detected by Linux And SCSI ID 4 reports vendor RaSCSI${SPACE*2} - And SCSI ID 4 reports revision 0147 + And SCSI ID 4 reports revision 0200 And SCSI ID 4 reports model CD-ROM CDU-55S${SPACE*2} And SCSI ID 4 reports type ${Scsi_device_type_cd_rom} @@ -89,6 +89,6 @@ Magneto Optical drive reports the correct device information Then Rasctl reports SCSI ID 5 of type MO And SCSI ID 5 is detected by Linux And SCSI ID 5 reports vendor RaSCSI${SPACE*2} - And SCSI ID 5 reports revision 0147 + And SCSI ID 5 reports revision 0200 And SCSI ID 5 reports model M2513A${SPACE*10} And SCSI ID 5 reports type ${Scsi_device_type_optical_memory} From bac4f4a80b993e5ddda83b6da695ea74998176fd Mon Sep 17 00:00:00 2001 From: akuker Date: Mon, 25 Jan 2021 13:27:21 -0600 Subject: [PATCH 05/22] Change reported version back to development build --- src/raspberrypi/rascsi_version.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raspberrypi/rascsi_version.cpp b/src/raspberrypi/rascsi_version.cpp index ee099f06..96975fdc 100644 --- a/src/raspberrypi/rascsi_version.cpp +++ b/src/raspberrypi/rascsi_version.cpp @@ -15,7 +15,7 @@ // The following should be updated for each release const int rascsi_major_version = 20; // Last two digits of year const int rascsi_minor_version = 12; // Month -const int rascsi_patch_version = 0; // Patch number - increment for each update +const int rascsi_patch_version = -1; // Patch number - increment for each update static char rascsi_version_string[30]; // Allow for string up to "XX.XX.XXX" + null character + "development build" From 788b2a3b46e7795c94fbd2f6dd980caa8ecddf0b Mon Sep 17 00:00:00 2001 From: Tony Kuker Date: Wed, 27 Jan 2021 15:16:52 -0600 Subject: [PATCH 06/22] Added DaynaPort SCSI/Link emulation functionality --- src/raspberrypi/Makefile | 11 +- src/raspberrypi/controllers/sasidev_ctrl.cpp | 483 +++++++--------- src/raspberrypi/controllers/sasidev_ctrl.h | 16 +- src/raspberrypi/controllers/scsidev_ctrl.cpp | 550 ++++++++++--------- src/raspberrypi/controllers/scsidev_ctrl.h | 79 ++- src/raspberrypi/devices/ctapdriver.cpp | 128 ++++- src/raspberrypi/devices/ctapdriver.h | 12 +- src/raspberrypi/devices/disk.cpp | 21 +- src/raspberrypi/devices/disk.h | 8 +- src/raspberrypi/devices/scsi_daynaport.cpp | 544 ++++++++++++++++++ src/raspberrypi/devices/scsi_daynaport.h | 199 +++++++ src/raspberrypi/devices/scsicd.cpp | 4 +- src/raspberrypi/devices/scsicd.h | 4 +- src/raspberrypi/devices/scsihd.cpp | 2 +- src/raspberrypi/gpiobus.h | 26 +- src/raspberrypi/launch_sudo.sh | 3 + src/raspberrypi/log.h | 48 +- src/raspberrypi/os.h | 7 +- src/raspberrypi/rascsi.cpp | 24 +- src/raspberrypi/rasctl.cpp | 25 +- src/raspberrypi/rasctl.h | 24 + src/raspberrypi/rasdump.cpp | 219 ++++---- src/raspberrypi/scsi.h | 92 +++- src/raspberrypi/setup_bridge.sh | 7 + 24 files changed, 1803 insertions(+), 733 deletions(-) create mode 100644 src/raspberrypi/devices/scsi_daynaport.cpp create mode 100644 src/raspberrypi/devices/scsi_daynaport.h create mode 100755 src/raspberrypi/launch_sudo.sh create mode 100644 src/raspberrypi/rasctl.h create mode 100755 src/raspberrypi/setup_bridge.sh diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 34d421a4..c2424c65 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -33,9 +33,9 @@ endif CFLAGS += -iquote . -MD -MP CXXFLAGS += -std=c++14 -iquote . -MD -MP -## CONNECT_TYPE=STANDARD : Specify the type of RaSCSI board type +## CONNECT_TYPE=FULLSPEC : Specify the type of RaSCSI board type ## that you are using. The typical options are -## STANDARD or FULLSPEC. The default is STANDARD +## STANDARD or FULLSPEC. The default is FULLSPEC ## * THIS IS TYPICALLY THE ONLY COMPILE OPTION YOU ## * NEED TO SPECIFY # If its not specified, build for FULLSPEC configuration @@ -88,11 +88,8 @@ SRC_SCSIMON = \ scsi.cpp \ gpiobus.cpp \ filepath.cpp \ - fileio.cpp\ + fileio.cpp \ rascsi_version.cpp -SRC_SCSIMON += $(shell find ./controllers -name '*.cpp') -SRC_SCSIMON += $(shell find ./devices -name '*.cpp') - SRC_RASCTL = \ rasctl.cpp\ @@ -154,7 +151,7 @@ ALL: all docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt $(BINDIR)/$(RASCSI): $(OBJ_RASCSI) | $(BINDIR) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread -lz $(BINDIR)/$(RASCTL): $(OBJ_RASCTL) | $(BINDIR) $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL) diff --git a/src/raspberrypi/controllers/sasidev_ctrl.cpp b/src/raspberrypi/controllers/sasidev_ctrl.cpp index 0cd1f420..6fc5987c 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.cpp +++ b/src/raspberrypi/controllers/sasidev_ctrl.cpp @@ -17,6 +17,8 @@ #include "filepath.h" #include "gpiobus.h" #include "devices/scsi_host_bridge.h" +#include "controllers/scsidev_ctrl.h" +#include "devices/scsi_daynaport.h" //=========================================================================== // @@ -44,7 +46,7 @@ SASIDEV::SASIDEV(Device *dev) // Work initialization ctrl.phase = BUS::busfree; - ctrl.id = -1; + ctrl.m_scsi_id = -1; ctrl.bus = NULL; memset(ctrl.cmd, 0x00, sizeof(ctrl.cmd)); ctrl.status = 0x00; @@ -52,7 +54,7 @@ SASIDEV::SASIDEV(Device *dev) #ifdef RASCSI ctrl.execstart = 0; #endif // RASCSI - ctrl.bufsize = 0x800; + ctrl.bufsize = ETH_FRAME_LEN + 16 + ETH_FCS_LEN; ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); memset(ctrl.buffer, 0x00, ctrl.bufsize); ctrl.blocks = 0; @@ -201,7 +203,7 @@ void FASTCALL SASIDEV::Connect(int id, BUS *bus) { ASSERT(this); - ctrl.id = id; + ctrl.m_scsi_id = id; ctrl.bus = bus; } @@ -291,7 +293,7 @@ BUS::phase_t FASTCALL SASIDEV::Process() ASSERT(this); // Do nothing if not connected - if (ctrl.id < 0 || ctrl.bus == NULL) { + if (ctrl.m_scsi_id < 0 || ctrl.bus == NULL) { return ctrl.phase; } @@ -301,9 +303,7 @@ BUS::phase_t FASTCALL SASIDEV::Process() // For the monitor tool, we shouldn't need to reset. We're just logging information // Reset if (ctrl.bus->GetRST()) { -#if defined(DISK_LOG) - Log(Log::Normal, "RESET signal received"); -#endif // DISK_LOG + LOGINFO("RESET signal received"); // Reset the controller Reset(); @@ -371,9 +371,7 @@ void FASTCALL SASIDEV::BusFree() // Phase change if (ctrl.phase != BUS::busfree) { -#if defined(DISK_LOG) - Log(Log::Normal, "Bus free phase"); -#endif // DISK_LOG + LOGINFO("Bus free phase"); // Phase Setting ctrl.phase = BUS::busfree; @@ -411,7 +409,7 @@ void FASTCALL SASIDEV::Selection() // Phase change if (ctrl.phase != BUS::selection) { // Invalid if IDs do not match - id = 1 << ctrl.id; + id = 1 << ctrl.m_scsi_id; if ((ctrl.bus->GetDAT() & id) == 0) { return; } @@ -421,10 +419,7 @@ void FASTCALL SASIDEV::Selection() return; } -#if defined(DISK_LOG) - Log(Log::Normal, - "Selection Phase ID=%d (with device)", ctrl.id); -#endif // DISK_LOG + LOGTRACE("%s Selection Phase ID=%d (with device)", __PRETTY_FUNCTION__, (int)ctrl.m_scsi_id); // Phase change ctrl.phase = BUS::selection; @@ -457,9 +452,7 @@ void FASTCALL SASIDEV::Command() // Phase change if (ctrl.phase != BUS::command) { -#if defined(DISK_LOG) - Log(Log::Normal, "Command Phase"); -#endif // DISK_LOG + LOGTRACE("%s Command Phase", __PRETTY_FUNCTION__); // Phase Setting ctrl.phase = BUS::command; @@ -537,9 +530,7 @@ void FASTCALL SASIDEV::Execute() { ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "Execution Phase Command %02X", ctrl.cmd[0]); -#endif // DISK_LOG + LOGTRACE("%s Execution Phase Command %02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[0]); // Phase Setting ctrl.phase = BUS::execute; @@ -552,65 +543,68 @@ void FASTCALL SASIDEV::Execute() #endif // RASCSI // Process by command - switch (ctrl.cmd[0]) { + switch ((SCSIDEV::scsi_command)ctrl.cmd[0]) { // TEST UNIT READY - case 0x00: + case SCSIDEV::eCmdTestUnitReady: CmdTestUnitReady(); return; // REZERO UNIT - case 0x01: + case SCSIDEV::eCmdRezero: CmdRezero(); return; // REQUEST SENSE - case 0x03: + case SCSIDEV::eCmdRequestSense: CmdRequestSense(); return; // FORMAT UNIT - case 0x04: - CmdFormat(); - return; - - // FORMAT UNIT - case 0x06: + // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. + // leaving it here for now.... + case SCSIDEV::eCmdFormat: CmdFormat(); return; // REASSIGN BLOCKS - case 0x07: + case SCSIDEV::eCmdReassign: CmdReassign(); return; // READ(6) - case 0x08: + case SCSIDEV::eCmdRead6: CmdRead6(); return; // WRITE(6) - case 0x0a: + case SCSIDEV::eCmdWrite6: CmdWrite6(); return; // SEEK(6) - case 0x0b: + case SCSIDEV::eCmdSeek6: CmdSeek6(); return; // ASSIGN(SASIのみ) - case 0x0e: + // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. + // leaving it here for now.... + case SCSIDEV::eCmdSasiCmdAssign: CmdAssign(); return; // SPECIFY(SASIのみ) - case 0xc2: + // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. + // leaving it here for now.... + case SCSIDEV::eCmdInvalid: CmdSpecify(); return; + default: + break; } // Unsupported command - Log(Log::Warning, "Unsupported command $%02X", ctrl.cmd[0]); + LOGWARN("%s Unsupported command $%02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[0]); CmdInvalid(); } @@ -645,9 +639,7 @@ void FASTCALL SASIDEV::Status() } #endif // RASCSI -#if defined(DISK_LOG) - Log(Log::Normal, "Status phase"); -#endif // DISK_LOG + LOGTRACE("%s Status phase", __PRETTY_FUNCTION__); // Phase Setting ctrl.phase = BUS::status; @@ -668,9 +660,7 @@ void FASTCALL SASIDEV::Status() ctrl.bus->SetDAT(ctrl.buffer[0]); ctrl.bus->SetREQ(TRUE); -#if defined(DISK_LOG) - Log(Log::Normal, "Status Phase $%02X", ctrl.status); -#endif // DISK_LOG + LOGTRACE( "%s Status Phase $%02X",__PRETTY_FUNCTION__, (unsigned int)ctrl.status); #endif // RASCSI return; } @@ -705,10 +695,7 @@ void FASTCALL SASIDEV::MsgIn() // Phase change if (ctrl.phase != BUS::msgin) { - -#if defined(DISK_LOG) - Log(Log::Normal, "Message in phase"); -#endif // DISK_LOG + LOGTRACE("%s Starting Message in phase", __PRETTY_FUNCTION__); // Phase Setting ctrl.phase = BUS::msgin; @@ -722,36 +709,12 @@ void FASTCALL SASIDEV::MsgIn() ASSERT(ctrl.length > 0); ASSERT(ctrl.blocks > 0); ctrl.offset = 0; - -#ifndef RASCSI - // Request message - ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); - ctrl.bus->SetREQ(TRUE); - -#if defined(DISK_LOG) - Log(Log::Normal, "Message in phase $%02X", ctrl.buffer[ctrl.offset]); -#endif // DISK_LOG -#endif // RASCSI return; } -#ifdef RASCSI //Send + LOGTRACE("%s Transitioning to Send()", __PRETTY_FUNCTION__); Send(); -#else - // Requesting - if (ctrl.bus->GetREQ()) { - // Initator received - if (ctrl.bus->GetACK()) { - SendNext(); - } - } else { - // Initiator requests next - if (!ctrl.bus->GetACK()) { - Send(); - } - } -#endif // RASCSI } //--------------------------------------------------------------------------- @@ -790,10 +753,7 @@ void FASTCALL SASIDEV::DataIn() return; } -#if defined(DISK_LOG) - Log(Log::Normal, "Data-in Phase"); -#endif // DISK_LOG - + LOGTRACE("%s Going into Data-in Phase", __PRETTY_FUNCTION__); // Phase Setting ctrl.phase = BUS::datain; @@ -807,33 +767,11 @@ void FASTCALL SASIDEV::DataIn() ASSERT(ctrl.blocks > 0); ctrl.offset = 0; -#ifndef RASCSI - // Assert the DAT signal - ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); - - // Request data - ctrl.bus->SetREQ(TRUE); -#endif // RASCSI return; } -#ifdef RASCSI // Send Send(); -#else - // Requesting - if (ctrl.bus->GetREQ()) { - // Initator received - if (ctrl.bus->GetACK()) { - SendNext(); - } - } else { - // Initiator requests next - if (!ctrl.bus->GetACK()) { - Send(); - } - } -#endif // RASCSI } //--------------------------------------------------------------------------- @@ -872,9 +810,7 @@ void FASTCALL SASIDEV::DataOut() return; } -#if defined(DISK_LOG) - Log(Log::Normal, "Data out phase"); -#endif // DISK_LOG + LOGTRACE("%s Data out phase", __PRETTY_FUNCTION__); // Phase Setting ctrl.phase = BUS::dataout; @@ -946,7 +882,7 @@ void FASTCALL SASIDEV::Error() } #if defined(DISK_LOG) - Log(Log::Warning, "Error occured (going to status phase)"); + LOGWARN("Error occured (going to status phase)"); #endif // DISK_LOG // Logical Unit @@ -971,9 +907,7 @@ void FASTCALL SASIDEV::CmdTestUnitReady() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "TEST UNIT READY Command "); -#endif // DISK_LOG + LOGTRACE("%s TEST UNIT READY Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1006,9 +940,7 @@ void FASTCALL SASIDEV::CmdRezero() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "REZERO UNIT Command "); -#endif // DISK_LOG + LOGTRACE( "%s REZERO UNIT Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1040,9 +972,7 @@ void FASTCALL SASIDEV::CmdRequestSense() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "REQUEST SENSE Command "); -#endif // DISK_LOG + LOGTRACE( "%s REQUEST SENSE Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1051,13 +981,11 @@ void FASTCALL SASIDEV::CmdRequestSense() return; } - // Command processing on drive ctrl.length = ctrl.unit[lun]->RequestSense(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length > 0); -#if defined(DISK_LOG) - Log(Log::Normal, "Sense key $%02X", ctrl.buffer[2]); -#endif // DISK_LOG + + LOGTRACE("%s Sense key $%02X",__PRETTY_FUNCTION__, (WORD)ctrl.buffer[2]); // Read phase DataIn(); @@ -1075,9 +1003,7 @@ void FASTCALL SASIDEV::CmdFormat() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "FORMAT UNIT Command "); -#endif // DISK_LOG + LOGTRACE( "%s FORMAT UNIT Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1110,9 +1036,7 @@ void FASTCALL SASIDEV::CmdReassign() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "REASSIGN BLOCKS Command "); -#endif // DISK_LOG + LOGTRACE("%s REASSIGN BLOCKS Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1163,13 +1087,82 @@ void FASTCALL SASIDEV::CmdRead6() ctrl.blocks = 0x100; } -#if defined(DISK_LOG) - Log(Log::Normal, - "READ(6) command record=%06X blocks=%d", record, ctrl.blocks); -#endif // DISK_LOG + if(ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'D', 'P')){ + // 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()); // Command processing on drive - ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record); + 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'))) { + // Failure (Error) + Error(); + return; + } + + // Set next block + ctrl.next = record + 1; + + // Read phase + DataIn(); +} + + +//--------------------------------------------------------------------------- +// +// This Send Message command is used by the DaynaPort SCSI/Link +// +//--------------------------------------------------------------------------- +void FASTCALL SASIDEV::DaynaPortWrite() +{ + DWORD lun; + DWORD data_format; + + ASSERT(this); + + // Logical Unit + lun = (ctrl.cmd[1] >> 5) & 0x07; + if (!ctrl.unit[lun]) { + Error(); + return; + } + + // Error if not a host bridge + if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')) { + LOGERROR("Received DaynaPortWrite for a non-DaynaPort device"); + Error(); + return; + } + + // Reallocate buffer (because it is not transfer for each block) + if (ctrl.bufsize < 0x1000000) { + free(ctrl.buffer); + ctrl.bufsize = 0x1000000; + ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); + } + + + data_format = ctrl.cmd[5]; + + + if(data_format == 0x00){ + ctrl.length = (WORD)ctrl.cmd[4] + ((WORD)ctrl.cmd[3] << 8); + } + else if (data_format == 0x80){ + ctrl.length = (WORD)ctrl.cmd[4] + ((WORD)ctrl.cmd[3] << 8) + 8; + } + else + { + LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)data_format); + } + LOGTRACE("%s length: %04X (%d) format: %02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.length, (int)ctrl.length, (unsigned int)data_format); + if (ctrl.length <= 0) { // Failure (Error) Error(); @@ -1177,12 +1170,14 @@ void FASTCALL SASIDEV::CmdRead6() } // Set next block - ctrl.next = record + 1; + ctrl.blocks = 1; + ctrl.next = 1; - // Read phase - DataIn(); + // Light phase + DataOut(); } + //--------------------------------------------------------------------------- // // WRITE(6) @@ -1202,6 +1197,12 @@ void FASTCALL SASIDEV::CmdWrite6() return; } + // Special receive function for the DaynaPort + if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'D', 'P')){ + DaynaPortWrite(); + return; + } + // Get record number and block number record = ctrl.cmd[1] & 0x1f; record <<= 8; @@ -1213,14 +1214,12 @@ void FASTCALL SASIDEV::CmdWrite6() ctrl.blocks = 0x100; } -#if defined(DISK_LOG) - Log(Log::Normal, - "WRITE(6) command record=%06X blocks=%d", record, ctrl.blocks); -#endif // DISK_LOG + LOGTRACE("%s WRITE(6) command record=%06X blocks=%d", __PRETTY_FUNCTION__, (WORD)record, (WORD)ctrl.blocks); // Command processing on drive ctrl.length = ctrl.unit[lun]->WriteCheck(record); if (ctrl.length <= 0) { + LOGDEBUG("WriteCheck failed"); // Failure (Error) Error(); return; @@ -1245,9 +1244,7 @@ void FASTCALL SASIDEV::CmdSeek6() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "SEEK(6) Command "); -#endif // DISK_LOG + LOGTRACE("%s SEEK(6) Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1280,9 +1277,7 @@ void FASTCALL SASIDEV::CmdAssign() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "ASSIGN Command "); -#endif // DISK_LOG + LOGTRACE("%s ASSIGN Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1318,9 +1313,7 @@ void FASTCALL SASIDEV::CmdSpecify() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "SPECIFY Command "); -#endif // DISK_LOG + LOGTRACE("%s SPECIFY Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1354,10 +1347,7 @@ void FASTCALL SASIDEV::CmdInvalid() DWORD lun; ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "Command not supported"); -#endif // DISK_LOG + LOGWARN("%s Command not supported", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1392,7 +1382,6 @@ void FASTCALL SASIDEV::Send() ASSERT(!ctrl.bus->GetREQ()); ASSERT(ctrl.bus->GetIO()); -#ifdef RASCSI // Check that the length isn't 0 if (ctrl.length != 0) { len = ctrl.bus->SendHandShake( @@ -1400,6 +1389,7 @@ void FASTCALL SASIDEV::Send() // If you can not send it all, move on to the status phase if (len != (int)ctrl.length) { + LOGERROR("%s ctrl.length (%d) did not match the amount of data sent (%d)",__PRETTY_FUNCTION__, (int)ctrl.length, len); Error(); return; } @@ -1409,20 +1399,9 @@ void FASTCALL SASIDEV::Send() ctrl.length = 0; return; } -#else - // Offset and Length - ASSERT(ctrl.length >= 1); - ctrl.offset++; - ctrl.length--; - - // Immediately after ACK is asserted, if the data - // has been set by SendNext, raise the request - if (ctrl.length != 0) { - // Signal line operated by the target - ctrl.bus->SetREQ(TRUE); - return; + else{ + LOGINFO("%s ctrl.length was 0", __PRETTY_FUNCTION__); } -#endif // RASCSI // Remove block and initialize the result ctrl.blocks--; @@ -1433,8 +1412,8 @@ void FASTCALL SASIDEV::Send() if (ctrl.blocks != 0) { // Set next buffer (set offset, length) result = XferIn(ctrl.buffer); - //** printf("xfer in: %d \n",result); - + LOGTRACE("%s xfer in: %d",__PRETTY_FUNCTION__, result); + LOGTRACE("%s processing after data collection", __PRETTY_FUNCTION__); #ifndef RASCSI ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); #endif // RASCSI @@ -1443,6 +1422,7 @@ void FASTCALL SASIDEV::Send() // If result FALSE, move to the status phase if (!result) { + LOGERROR("%s Send result was false", __PRETTY_FUNCTION__); Error(); return; } @@ -1538,9 +1518,7 @@ void FASTCALL SASIDEV::Receive() // Command phase case BUS::command: ctrl.cmd[ctrl.offset] = data; -#if defined(DISK_LOG) - Log(Log::Normal, "Command phase $%02X", data); -#endif // DISK_LOG + LOGTRACE( "%s Command phase $%02X", __PRETTY_FUNCTION__, data); // Set the length again with the first data (offset 0) if (ctrl.offset == 0) { @@ -1597,6 +1575,7 @@ void FASTCALL SASIDEV::ReceiveNext() // Receive len = ctrl.bus->ReceiveHandShake( &ctrl.buffer[ctrl.offset], ctrl.length); + LOGDEBUG("%s Received %d bytes", __PRETTY_FUNCTION__, len); // If not able to receive all, move to status phase if (len != (int)ctrl.length) { @@ -1609,6 +1588,10 @@ void FASTCALL SASIDEV::ReceiveNext() ctrl.length = 0; return; } + else + { + LOGDEBUG("%s ctrl.length was 0", __PRETTY_FUNCTION__); + } #else // Offset and Length ASSERT(ctrl.length >= 1); @@ -1667,6 +1650,7 @@ void FASTCALL SASIDEV::ReceiveNext() // Data out phase case BUS::dataout: + LOGTRACE("%s transitioning to FlushUnit()",__PRETTY_FUNCTION__); // Flush FlushUnit(); @@ -1693,6 +1677,7 @@ BOOL FASTCALL SASIDEV::XferIn(BYTE *buf) ASSERT(this); ASSERT(ctrl.phase == BUS::datain); + LOGTRACE("%s ctrl.cmd[0]=%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[0]); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1707,7 +1692,7 @@ BOOL FASTCALL SASIDEV::XferIn(BYTE *buf) // READ(10) case 0x28: // Read from disk - ctrl.length = ctrl.unit[lun]->Read(buf, ctrl.next); + ctrl.length = ctrl.unit[lun]->Read(ctrl.cmd, buf, ctrl.next); ctrl.next++; // If there is an error, go to the status phase @@ -1750,12 +1735,9 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) return FALSE; } - // MODE SELECT or WRITE system - switch (ctrl.cmd[0]) { - // MODE SELECT - case 0x15: - // MODE SELECT(10) - case 0x55: + switch ((SCSIDEV::scsi_command) ctrl.cmd[0]) { + case SCSIDEV::eCmdModeSelect: + case SCSIDEV::eCmdModeSelect10: if (!ctrl.unit[lun]->ModeSelect( ctrl.cmd, ctrl.buffer, ctrl.offset)) { // MODE SELECT failed @@ -1763,11 +1745,11 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) } break; - // WRITE(6) - case 0x0a: - // WRITE(10) - case 0x2a: - // Replace the host bridge with SEND MESSAGE 10 + case SCSIDEV::eCmdWrite6: + case SCSIDEV::eCmdWrite10: + case SCSIDEV::eCmdWriteAndVerify10: + // If we're a host bridge, use the host bridge's SendMessage10 + // function if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) { bridge = (SCSIBR*)ctrl.unit[lun]; if (!bridge->SendMessage10(ctrl.cmd, ctrl.buffer)) { @@ -1780,10 +1762,23 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) break; } - // WRITE AND VERIFY - case 0x2e: - // Write - if (!ctrl.unit[lun]->Write(ctrl.buffer, ctrl.next - 1)) { + // Special case Write function for DaynaPort + if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'D', 'P')) { + LOGTRACE("%s Doing special case write for DayanPort", __PRETTY_FUNCTION__); + if (!(SCSIDaynaPort*)ctrl.unit[lun]->Write(ctrl.cmd, ctrl.buffer, ctrl.length)) { + // write failed + return FALSE; + } + LOGTRACE("%s Done with DaynaPort Write", __PRETTY_FUNCTION__); + + // If normal, work setting + ctrl.offset = 0; + ctrl.blocks = 0; + break; + } + + LOGTRACE("%s eCmdWriteAndVerify10 Calling Write... cmd: %02X next: %d", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd, (int)ctrl.next); + if (!ctrl.unit[lun]->Write(ctrl.cmd, ctrl.buffer, ctrl.next - 1)) { // Write failed return FALSE; } @@ -1806,10 +1801,14 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) break; // SPECIFY(SASI only) - case 0xc2: + case SCSIDEV::eCmdInvalid: break; + case SCSIDEV::eCmdSetMcastAddr: + LOGTRACE("%s Done with DaynaPort Set Multicast Address", __PRETTY_FUNCTION__); + break; default: + LOGWARN("Received an unexpected command (%02X) in %s", (WORD)ctrl.cmd[0] , __PRETTY_FUNCTION__) ASSERT(FALSE); break; } @@ -1837,45 +1836,49 @@ void FASTCALL SASIDEV::FlushUnit() } // WRITE system only - switch (ctrl.cmd[0]) { - // WRITE(6) - case 0x0a: - // WRITE(10) - case 0x2a: - // WRITE AND VERIFY - case 0x2e: + switch ((SCSIDEV::scsi_command)ctrl.cmd[0]) { + case SCSIDEV::eCmdWrite6: + case SCSIDEV::eCmdWrite10: + case SCSIDEV::eCmdWriteAndVerify10: // Flush if (!ctrl.unit[lun]->IsCacheWB()) { ctrl.unit[lun]->Flush(); } break; - // Mode Select (6) - case 0x15: - // MODE SELECT(10) - case 0x55: + case SCSIDEV::eCmdModeSelect: + case SCSIDEV::eCmdModeSelect10: // Debug code related to Issue #2 on github, where we get an unhandled Model select when // the mac is rebooted // https://github.com/akuker/RASCSI/issues/2 - Log(Log::Warning, "Received \'Mode Select\'\n"); - Log(Log::Warning, " Operation Code: [%02X]\n", ctrl.cmd[0]); - Log(Log::Warning, " Logical Unit %01X, PF %01X, SP %01X [%02X]\n", ctrl.cmd[1] >> 5, 1 & (ctrl.cmd[1] >> 4), ctrl.cmd[1] & 1, ctrl.cmd[1]); - Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[2]); - Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[3]); - Log(Log::Warning, " Parameter List Len %02X\n", ctrl.cmd[4]); - Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[5]); - Log(Log::Warning, " Ctrl Len: %08X\n",ctrl.length); + LOGWARN("Received \'Mode Select\'\n"); + LOGWARN(" Operation Code: [%02X]\n", (WORD)ctrl.cmd[0]); + LOGWARN(" Logical Unit %01X, PF %01X, SP %01X [%02X]\n",\ + (WORD)ctrl.cmd[1] >> 5, 1 & ((WORD)ctrl.cmd[1] >> 4), \ + (WORD)ctrl.cmd[1] & 1, (WORD)ctrl.cmd[1]); + LOGWARN(" Reserved: %02X\n", (WORD)ctrl.cmd[2]); + LOGWARN(" Reserved: %02X\n", (WORD)ctrl.cmd[3]); + LOGWARN(" Parameter List Len %02X\n", (WORD)ctrl.cmd[4]); + LOGWARN(" Reserved: %02X\n",(WORD)ctrl.cmd[5]); + LOGWARN(" Ctrl Len: %08X\n",(WORD)ctrl.length); if (!ctrl.unit[lun]->ModeSelect( ctrl.cmd, ctrl.buffer, ctrl.offset)) { // MODE SELECT failed - Log(Log::Warning, "Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]); + LOGWARN("Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]); return; } break; - + case SCSIDEV::eCmdSetIfaceMode: + LOGWARN("%s Trying to flush a command set interface mode. This should be a daynaport?", __PRETTY_FUNCTION__); + break; + case SCSIDEV::eCmdSetMcastAddr: + // TODO: Eventually, we should store off the multicast address configuration data here... + break; default: - Log(Log::Warning, "Received an invalid flush command %02X!!!!!\n",ctrl.cmd[0]); - ASSERT(FALSE); + LOGWARN("Received an unexpected flush command %02X!!!!!\n",(WORD)ctrl.cmd[0]); + // The following statement makes debugging a huge pain. You can un-comment it + // if you're not trying to add new devices.... + // ASSERT(FALSE); break; } } @@ -1929,71 +1932,3 @@ void SASIDEV::GetPhaseStr(char *str) } } #endif - -//--------------------------------------------------------------------------- -// -// Log output -// -// TODO: This function needs some cleanup. Its very kludgey -//--------------------------------------------------------------------------- -void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...) -{ -#if !defined(BAREMETAL) -#ifdef DISK_LOG - char buffer[0x200]; - char buffer2[0x250]; - char buffer3[0x250]; - char phase_str[20]; -#endif - va_list args; - va_start(args, format); - - if(this->GetID() != 6) - { - return; - } - -#ifdef RASCSI -#ifndef DISK_LOG - if (level == Log::Warning) { - return; - } -#endif // DISK_LOG -#endif // RASCSI - -#ifdef DISK_LOG - // format - vsprintf(buffer, format, args); - - // end variable length argument - va_end(args); - - // Add the date/timestamp - // current date/time based on current system - time_t now = time(0); - // convert now to string form - char* dt = ctime(&now); - - - strcpy(buffer2, "["); - strcat(buffer2, dt); - // Get rid of the carriage return - buffer2[strlen(buffer2)-1] = '\0'; - strcat(buffer2, "] "); - - // Get the phase - this->GetPhaseStr(phase_str); - sprintf(buffer3, "[%d][%s] ", this->GetID(), phase_str); - strcat(buffer2,buffer3); - strcat(buffer2, buffer); - - - // Log output -#ifdef RASCSI - printf("%s\n", buffer2); -#else - host->GetVM()->GetLog()->Format(level, host, buffer); -#endif // RASCSI -#endif // BAREMETAL -#endif // DISK_LOG -} diff --git a/src/raspberrypi/controllers/sasidev_ctrl.h b/src/raspberrypi/controllers/sasidev_ctrl.h index fc8ec2d0..7f7bfb3f 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.h +++ b/src/raspberrypi/controllers/sasidev_ctrl.h @@ -46,9 +46,9 @@ public: // Internal data definition typedef struct { - // 全般 + // General BUS::phase_t phase; // Transition phase - int id; // Controller ID (0-7) + int m_scsi_id; // Controller ID (0-7) BUS *bus; // Bus // commands @@ -116,7 +116,7 @@ public: void FASTCALL GetPhaseStr(char *str); #endif - int FASTCALL GetID() {return ctrl.id;} + int FASTCALL GetSCSIID() {return ctrl.m_scsi_id;} // Get the ID void FASTCALL GetCTRL(ctrl_t *buffer); // Get the internal information @@ -161,9 +161,9 @@ protected: // FORMAT command void FASTCALL CmdReassign(); // REASSIGN BLOCKS command - void FASTCALL CmdRead6(); + virtual void FASTCALL CmdRead6(); // READ(6) command - void FASTCALL CmdWrite6(); + virtual void FASTCALL CmdWrite6(); // WRITE(6) command void FASTCALL CmdSeek6(); // SEEK(6) command @@ -173,6 +173,8 @@ protected: // SPECIFY command void FASTCALL CmdInvalid(); // Unsupported command + void FASTCALL DaynaPortWrite(); + // DaynaPort specific 'write' operation // データ転送 virtual void FASTCALL Send(); @@ -196,10 +198,6 @@ protected: void FASTCALL FlushUnit(); // Flush the logical unit - // Log - void FASTCALL Log(Log::loglevel level, const char *format, ...); - // Log output - protected: #ifndef RASCSI Device *host; diff --git a/src/raspberrypi/controllers/scsidev_ctrl.cpp b/src/raspberrypi/controllers/scsidev_ctrl.cpp index a496eeb4..ce5417a2 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.cpp +++ b/src/raspberrypi/controllers/scsidev_ctrl.cpp @@ -13,10 +13,11 @@ // [ SCSI device controller ] // //--------------------------------------------------------------------------- +#include "log.h" #include "controllers/scsidev_ctrl.h" #include "gpiobus.h" #include "devices/scsi_host_bridge.h" -#include "rascsi_version.h" +#include "devices/scsi_daynaport.h" //=========================================================================== // @@ -72,18 +73,16 @@ BUS::phase_t FASTCALL SCSIDEV::Process() ASSERT(this); // Do nothing if not connected - if (ctrl.id < 0 || ctrl.bus == NULL) { + if (ctrl.m_scsi_id < 0 || ctrl.bus == NULL) { return ctrl.phase; } // Get bus information ((GPIOBUS*)ctrl.bus)->Aquire(); - // Reset + // Check to see if the reset signal was asserted if (ctrl.bus->GetRST()) { -#if defined(DISK_LOG) - Log(Log::Normal, "RESET信号受信"); -#endif // DISK_LOG + LOGWARN("RESET signal received!"); // Reset the controller Reset(); @@ -146,7 +145,7 @@ BUS::phase_t FASTCALL SCSIDEV::Process() //--------------------------------------------------------------------------- // -// Phaes +// Phases // //--------------------------------------------------------------------------- @@ -162,9 +161,7 @@ void FASTCALL SCSIDEV::BusFree() // Phase change if (ctrl.phase != BUS::busfree) { -#if defined(DISK_LOG) - Log(Log::Normal, "Bus free phase"); -#endif // DISK_LOG + LOGTRACE( "%s Bus free phase", __PRETTY_FUNCTION__); // Phase setting ctrl.phase = BUS::busfree; @@ -205,7 +202,7 @@ void FASTCALL SCSIDEV::Selection() // Phase change if (ctrl.phase != BUS::selection) { // invalid if IDs do not match - id = 1 << ctrl.id; + id = 1 << ctrl.m_scsi_id; if ((ctrl.bus->GetDAT() & id) == 0) { return; } @@ -215,10 +212,7 @@ void FASTCALL SCSIDEV::Selection() return; } -#if defined(DISK_LOG) - Log(Log::Normal, - "Selection Phase ID=%d (with device)", ctrl.id); -#endif // DISK_LOG + LOGTRACE("%s Selection Phase ID=%d (with device)", __PRETTY_FUNCTION__, (int)ctrl.m_scsi_id); // Phase setting ctrl.phase = BUS::selection; @@ -248,9 +242,7 @@ void FASTCALL SCSIDEV::Execute() { ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "Execution phase command $%02X", ctrl.cmd[0]); -#endif // DISK_LOG + LOGTRACE( "%s Execution phase command $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[0]); // Phase Setting ctrl.phase = BUS::execute; @@ -263,157 +255,188 @@ void FASTCALL SCSIDEV::Execute() #endif // RASCSI // Process by command - switch (ctrl.cmd[0]) { + switch ((scsi_command)ctrl.cmd[0]) { // TEST UNIT READY - case 0x00: + case eCmdTestUnitReady: + LOGDEBUG("++++ CMD ++++ %s Received eCmdTestUnitReady", __PRETTY_FUNCTION__); CmdTestUnitReady(); return; // REZERO - case 0x01: + case eCmdRezero: CmdRezero(); return; // REQUEST SENSE - case 0x03: + case eCmdRequestSense: + LOGDEBUG("++++ CMD ++++ %s Received eCmdRequestSense", __PRETTY_FUNCTION__); CmdRequestSense(); return; // FORMAT UNIT - case 0x04: + case eCmdFormat: CmdFormat(); return; // REASSIGN BLOCKS - case 0x07: + case eCmdReassign: CmdReassign(); return; // READ(6) - case 0x08: + case eCmdRead6: + LOGTRACE("++++ CMD ++++ %s Received eCmdRead6", __PRETTY_FUNCTION__); CmdRead6(); return; + case eCmdRetrieveStats: + LOGDEBUG("++++ CMD ++++ %s Received eCmdRetrieveStats", __PRETTY_FUNCTION__); + CmdRetrieveStats(); + return; + + case eCmdSetIfaceMode: + LOGDEBUG("++++ CMD ++++ %s Received eCmdSetIfaceMode", __PRETTY_FUNCTION__); + CmdSetIfaceMode(); + return; + + case eCmdSetMcastAddr: + LOGDEBUG("++++ CMD ++++ %s Received eCmdSetMcastAddr", __PRETTY_FUNCTION__); + CmdSetMcastAddr(); + return; + + case eCmdEnableInterface: + LOGDEBUG("++++ CMD ++++ %s Received eCmdEnableInterface", __PRETTY_FUNCTION__); + CmdEnableInterface(); + return; + // WRITE(6) - case 0x0a: + case eCmdWrite6: + LOGDEBUG("++++ CMD ++++ %s Received eCmdWrite6", __PRETTY_FUNCTION__); CmdWrite6(); return; // SEEK(6) - case 0x0b: + case eCmdSeek6: + LOGDEBUG("++++ CMD ++++ %s Received eCmdSeek6", __PRETTY_FUNCTION__); CmdSeek6(); return; // INQUIRY - case 0x12: + case eCmdInquiry: + LOGDEBUG("++++ CMD ++++ %s Received eCmdInquiry", __PRETTY_FUNCTION__); CmdInquiry(); return; // MODE SELECT - case 0x15: + case eCmdModeSelect: + LOGDEBUG("++++ CMD ++++ %s Received eCmdModeSelect", __PRETTY_FUNCTION__); CmdModeSelect(); return; - // MDOE SENSE - case 0x1a: + // MODE SENSE + case eCmdModeSense: + LOGDEBUG("++++ CMD ++++ %s Received eCmdModeSense", __PRETTY_FUNCTION__); CmdModeSense(); return; // START STOP UNIT - case 0x1b: + case eCmdStartStop: + LOGDEBUG("++++ CMD ++++ %s Received eCmdStartStop", __PRETTY_FUNCTION__); CmdStartStop(); return; // SEND DIAGNOSTIC - case 0x1d: + case eCmdSendDiag: + LOGDEBUG("++++ CMD ++++ %s Received eCmdSendDiag", __PRETTY_FUNCTION__); CmdSendDiag(); return; // PREVENT/ALLOW MEDIUM REMOVAL - case 0x1e: + case eCmdRemoval: CmdRemoval(); return; // READ CAPACITY - case 0x25: + case eCmdReadCapacity: CmdReadCapacity(); return; // READ(10) - case 0x28: + case eCmdRead10: + LOGDEBUG("++++ CMD ++++ %s Received eCmdRead10", __PRETTY_FUNCTION__); CmdRead10(); return; // WRITE(10) - case 0x2a: + // WRITE and VERIFY(10) + case eCmdWrite10: + case eCmdWriteAndVerify10: + LOGDEBUG("++++ CMD ++++ %s Received eCmdWrite10", __PRETTY_FUNCTION__); CmdWrite10(); return; // SEEK(10) - case 0x2b: + case eCmdSeek10: CmdSeek10(); return; - // WRITE and VERIFY - case 0x2e: - CmdWrite10(); - return; - // VERIFY - case 0x2f: + case eCmdVerify: CmdVerify(); return; // SYNCHRONIZE CACHE - case 0x35: + case eCmdSynchronizeCache: CmdSynchronizeCache(); return; // READ DEFECT DATA(10) - case 0x37: + case eCmdReadDefectData10: CmdReadDefectData10(); return; // READ TOC - case 0x43: + case eCmdReadToc: CmdReadToc(); return; // PLAY AUDIO(10) - case 0x45: + case eCmdPlayAudio10: CmdPlayAudio10(); return; // PLAY AUDIO MSF - case 0x47: + case eCmdPlayAudioMSF: CmdPlayAudioMSF(); return; // PLAY AUDIO TRACK - case 0x48: + case eCmdPlayAudioTrack: CmdPlayAudioTrack(); return; // MODE SELECT(10) - case 0x55: + case eCmdModeSelect10: CmdModeSelect10(); return; // MDOE SENSE(10) - case 0x5a: + case eCmdModeSense10: CmdModeSense10(); return; // SPECIFY (SASI only/Suppress warning when using SxSI) - case 0xc2: + case eCmdInvalid: CmdInvalid(); return; + default: + // No other support + LOGWARN("%s Received unsupported command: $%02X", __PRETTY_FUNCTION__, (BYTE)ctrl.cmd[0]); + CmdInvalid(); } + return; - // No other support - Log(Log::Normal, "Unsupported command received: $%02X", ctrl.cmd[0]); - CmdInvalid(); } //--------------------------------------------------------------------------- @@ -424,13 +447,12 @@ void FASTCALL SCSIDEV::Execute() void FASTCALL SCSIDEV::MsgOut() { ASSERT(this); + LOGTRACE("%s ID: %d",__PRETTY_FUNCTION__, this->GetSCSIID()); // Phase change if (ctrl.phase != BUS::msgout) { -#if defined(DISK_LOG) - Log(Log::Normal, "Message Out Phase"); -#endif // DISK_LOG + LOGTRACE("Message Out Phase"); // Message out phase after selection // process the IDENTIFY message @@ -460,23 +482,8 @@ void FASTCALL SCSIDEV::MsgOut() return; } -#ifdef RASCSI // Receive Receive(); -#else - // Requesting - if (ctrl.bus->GetREQ()) { - // Sent by the initiator - if (ctrl.bus->GetACK()) { - Receive(); - } - } else { - // Request the initator to - if (!ctrl.bus->GetACK()) { - ReceiveNext(); - } - } -#endif // RASCSI } //--------------------------------------------------------------------------- @@ -507,9 +514,7 @@ void FASTCALL SCSIDEV::Error() return; } -#if defined(DISK_LOG) - Log(Log::Normal, "Error (to status phase)"); -#endif // DISK_LOG + LOGTRACE( "%s Error (to status phase)", __PRETTY_FUNCTION__); // Set status and message(CHECK CONDITION) ctrl.status = 0x02; @@ -539,9 +544,7 @@ void FASTCALL SCSIDEV::CmdInquiry() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "INQUIRY Command"); -#endif // DISK_LOG + LOGTRACE("%s INQUIRY Command", __PRETTY_FUNCTION__); // Find a valid unit disk = NULL; @@ -554,8 +557,9 @@ void FASTCALL SCSIDEV::CmdInquiry() // Processed on the disk side (it is originally processed by the controller) if (disk) { - major = (DWORD)rascsi_major_version; - minor = (DWORD)rascsi_minor_version; + major = (DWORD)(RASCSI >> 8); + minor = (DWORD)(RASCSI & 0xff); + LOGINFO("%s Buffer size is %d",__PRETTY_FUNCTION__, ctrl.bufsize); ctrl.length = ctrl.unit[lun]->Inquiry(ctrl.cmd, ctrl.buffer, major, minor); } else { @@ -588,9 +592,7 @@ void FASTCALL SCSIDEV::CmdModeSelect() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SELECT Command"); -#endif // DISK_LOG + LOGTRACE( "%s MODE SELECT Command", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -622,9 +624,7 @@ void FASTCALL SCSIDEV::CmdModeSense() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SENSE Command "); -#endif // DISK_LOG + LOGTRACE( "%s MODE SENSE Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -637,8 +637,7 @@ void FASTCALL SCSIDEV::CmdModeSense() ctrl.length = ctrl.unit[lun]->ModeSense(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length >= 0); if (ctrl.length == 0) { - Log(Log::Warning, - "Not supported MODE SENSE page $%02X", ctrl.cmd[2]); + LOGWARN("%s Not supported MODE SENSE page $%02X",__PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[2]); // Failure (Error) Error(); @@ -661,9 +660,7 @@ void FASTCALL SCSIDEV::CmdStartStop() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "START STOP UNIT Command "); -#endif // DISK_LOG + LOGTRACE( "%s START STOP UNIT Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -696,9 +693,7 @@ void FASTCALL SCSIDEV::CmdSendDiag() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "SEND DIAGNOSTIC Command "); -#endif // DISK_LOG + LOGTRACE( "%s SEND DIAGNOSTIC Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -731,9 +726,7 @@ void FASTCALL SCSIDEV::CmdRemoval() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "PREVENT/ALLOW MEDIUM REMOVAL Command "); -#endif // DISK_LOG + LOGTRACE( "%s PREVENT/ALLOW MEDIUM REMOVAL Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -766,9 +759,7 @@ void FASTCALL SCSIDEV::CmdReadCapacity() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "READ CAPACITY Command "); -#endif // DISK_LOG + LOGTRACE( "%s READ CAPACITY Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -829,9 +820,7 @@ void FASTCALL SCSIDEV::CmdRead10() ctrl.blocks <<= 8; ctrl.blocks |= ctrl.cmd[8]; -#if defined(DISK_LOG) - Log(Log::Normal, "READ(10) command record=%08X block=%d", record, ctrl.blocks); -#endif // DISK_LOG + LOGTRACE("%s READ(10) command record=%08X block=%d", __PRETTY_FUNCTION__, (unsigned int)record, (int)ctrl.blocks); // Do not process 0 blocks if (ctrl.blocks == 0) { @@ -840,7 +829,7 @@ void FASTCALL SCSIDEV::CmdRead10() } // Command processing on drive - ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record); + ctrl.length = ctrl.unit[lun]->Read(ctrl.cmd, ctrl.buffer, record); if (ctrl.length <= 0) { // Failure (Error) Error(); @@ -891,10 +880,7 @@ void FASTCALL SCSIDEV::CmdWrite10() ctrl.blocks <<= 8; ctrl.blocks |= ctrl.cmd[8]; -#if defined(DISK_LOG) - Log(Log::Normal, - "WRTIE(10) command record=%08X blocks=%d", record, ctrl.blocks); -#endif // DISK_LOG + LOGTRACE("%s WRTIE(10) command record=%08X blocks=%d",__PRETTY_FUNCTION__, (unsigned int)record, (unsigned int)ctrl.blocks); // Do not process 0 blocks if (ctrl.blocks == 0) { @@ -929,9 +915,7 @@ void FASTCALL SCSIDEV::CmdSeek10() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "SEEK(10) Command "); -#endif // DISK_LOG + LOGTRACE( "%s SEEK(10) Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -984,10 +968,7 @@ void FASTCALL SCSIDEV::CmdVerify() ctrl.blocks <<= 8; ctrl.blocks |= ctrl.cmd[8]; -#if defined(DISK_LOG) - Log(Log::Normal, - "VERIFY command record=%08X blocks=%d", record, ctrl.blocks); -#endif // DISK_LOG + LOGTRACE("%s VERIFY command record=%08X blocks=%d",__PRETTY_FUNCTION__, (unsigned int)record, (int)ctrl.blocks); // Do not process 0 blocks if (ctrl.blocks == 0) { @@ -1011,7 +992,7 @@ void FASTCALL SCSIDEV::CmdVerify() } // Test loading - ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record); + ctrl.length = ctrl.unit[lun]->Read(ctrl.cmd, ctrl.buffer, record); if (ctrl.length <= 0) { // Failure (Error) Error(); @@ -1060,9 +1041,7 @@ void FASTCALL SCSIDEV::CmdReadDefectData10() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "READ DEFECT DATA(10) Command "); -#endif // DISK_LOG + LOGTRACE( "%s READ DEFECT DATA(10) Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1218,9 +1197,7 @@ void FASTCALL SCSIDEV::CmdModeSelect10() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SELECT10 Command "); -#endif // DISK_LOG + LOGTRACE( "%s MODE SELECT10 Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1252,9 +1229,7 @@ void FASTCALL SCSIDEV::CmdModeSense10() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SENSE(10) Command "); -#endif // DISK_LOG + LOGTRACE( "%s MODE SENSE(10) Command ", __PRETTY_FUNCTION__); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1267,8 +1242,7 @@ void FASTCALL SCSIDEV::CmdModeSense10() ctrl.length = ctrl.unit[lun]->ModeSense10(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length >= 0); if (ctrl.length == 0) { - Log(Log::Warning, - "Not supported MODE SENSE(10) page $%02X", ctrl.cmd[2]); + LOGWARN("%s Not supported MODE SENSE(10) page $%02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[2]); // Failure (Error) Error(); @@ -1299,7 +1273,9 @@ void FASTCALL SCSIDEV::CmdGetMessage10() } // Error if not a host bridge - if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) { + if ((ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) && + (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'N', 'L'))){ + LOGWARN("Received a GetMessage10 command for a non-bridge unit"); Error(); return; } @@ -1333,6 +1309,8 @@ void FASTCALL SCSIDEV::CmdGetMessage10() // // SEND MESSAGE(10) // +// This Send Message command is used by the X68000 host driver +// //--------------------------------------------------------------------------- void FASTCALL SCSIDEV::CmdSendMessage10() { @@ -1349,6 +1327,7 @@ void FASTCALL SCSIDEV::CmdSendMessage10() // Error if not a host bridge if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) { + LOGERROR("Received CmdSendMessage10 for a non-bridge device"); Error(); return; } @@ -1381,6 +1360,186 @@ void FASTCALL SCSIDEV::CmdSendMessage10() DataOut(); } +//--------------------------------------------------------------------------- +// +// Retrieve Statistics (09) +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::CmdRetrieveStats() +{ + DWORD lun; + SCSIDaynaPort *dayna_port; + + ASSERT(this); + + // Logical Unit + lun = (ctrl.cmd[1] >> 5) & 0x07; + if (!ctrl.unit[lun]) { + Error(); + return; + } + + // 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()); + Error(); + return; + } + + // Process with drive + dayna_port = (SCSIDaynaPort*)ctrl.unit[lun]; + ctrl.length = dayna_port->RetrieveStats(ctrl.cmd, ctrl.buffer); + + if (ctrl.length <= 0) { + // Failure (Error) + Error(); + return; + } + + // Set next block + ctrl.blocks = 1; + ctrl.next = 1; + + // Data in phase + DataIn(); +} + +//--------------------------------------------------------------------------- +// +// Set Interface Mode (0c) +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::CmdSetIfaceMode() +{ + DWORD lun; + // BOOL status; + SCSIDaynaPort *dayna_port; + + ASSERT(this); + + LOGTRACE("%s",__PRETTY_FUNCTION__); + + // Logical Unit + lun = (ctrl.cmd[1] >> 5) & 0x07; + if (!ctrl.unit[lun]) { + Error(); + return; + } + + // 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()); + Error(); + return; + } + + dayna_port = (SCSIDaynaPort*)ctrl.unit[lun]; + + // Check whether this command is telling us to "Set Interface Mode" + // or "Set MAC Address" + + ctrl.length = dayna_port->RetrieveStats(ctrl.cmd, ctrl.buffer); + switch(ctrl.cmd[5]){ + case SCSIDaynaPort::CMD_SCSILINK_SETMODE: + dayna_port->SetMode(ctrl.cmd, ctrl.buffer); + Status(); + break; + break; + case SCSIDaynaPort::CMD_SCSILINK_SETMAC: + ctrl.length = 6; + // Write phase + DataOut(); + break; + default: + LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[5]); + } +} + +//--------------------------------------------------------------------------- +// +// Set the multicast address +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::CmdSetMcastAddr() +{ + DWORD lun; + + ASSERT(this); + + LOGTRACE("%s Set Multicast Address Command ", __PRETTY_FUNCTION__); + + // Logical Unit + lun = (ctrl.cmd[1] >> 5) & 0x07; + if (!ctrl.unit[lun]) { + Error(); + return; + } + + if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){ + LOGWARN("Received a SetMcastAddress command for a non-daynaport unit"); + Error(); + return; + } + + // Command processing on drive + ctrl.length = (DWORD)ctrl.cmd[4]; + + // ASSERT(ctrl.length >= 0); + if (ctrl.length == 0) { + LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[2]); + + // Failure (Error) + Error(); + return; + } + + DataOut(); +} + +//--------------------------------------------------------------------------- +// +// Enable/disable Interface (0e) +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::CmdEnableInterface() +{ + DWORD lun=0; + BOOL status; + SCSIDaynaPort *dayna_port; + + ASSERT(this); + + LOGTRACE("%s",__PRETTY_FUNCTION__); + + // Logical Unit + lun = (ctrl.cmd[1] >> 5) & 0x07; + if (!ctrl.unit[lun]) { + Error(); + return; + } + + // 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()); + Error(); + return; + } + + dayna_port = (SCSIDaynaPort*)ctrl.unit[lun]; + + // Command processing on drive + status = dayna_port->EnableInterface(ctrl.cmd); + if (!status) { + // Failure (Error) + Error(); + return; + } + + // status phase + Status(); +} + + //=========================================================================== // // Data Transfer @@ -1406,6 +1565,7 @@ void FASTCALL SCSIDEV::Send() #ifdef RASCSI //if Length! = 0, send if (ctrl.length != 0) { + LOGTRACE("%s sending handhake with offset %lu, length %lu", __PRETTY_FUNCTION__, ctrl.offset, ctrl.length); len = ctrl.bus->SendHandShake( &ctrl.buffer[ctrl.offset], ctrl.length); @@ -1444,6 +1604,7 @@ void FASTCALL SCSIDEV::Send() if (ctrl.blocks != 0) { // // set next buffer (set offset, length) result = XferIn(ctrl.buffer); + LOGTRACE("%s processing after data collection. Blocks: %lu", __PRETTY_FUNCTION__, ctrl.blocks); #ifndef RASCSI ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); #endif // RASCSI @@ -1458,6 +1619,7 @@ void FASTCALL SCSIDEV::Send() // Continue sending if block !=0 if (ctrl.blocks != 0){ + LOGTRACE("%s Continuing to send. blocks = %lu", __PRETTY_FUNCTION__, ctrl.blocks); ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); #ifndef RASCSI @@ -1468,6 +1630,7 @@ void FASTCALL SCSIDEV::Send() } // Move to next phase + LOGTRACE("%s Move to next phase %s (%d)", __PRETTY_FUNCTION__, BUS::GetPhaseStrRaw(ctrl.phase), ctrl.phase); switch (ctrl.phase) { // Message in phase case BUS::msgin: @@ -1530,132 +1693,52 @@ void FASTCALL SCSIDEV::SendNext() } #endif // RASCSI -#ifndef RASCSI -//--------------------------------------------------------------------------- -// -// Receive data -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIDEV::Receive() -{ - DWORD data; - - ASSERT(this); - - // Req is up - ASSERT(ctrl.bus->GetREQ()); - ASSERT(!ctrl.bus->GetIO()); - - // Get data - data = (DWORD)ctrl.bus->GetDAT(); - - // Signal line operated by the target - ctrl.bus->SetREQ(FALSE); - - switch (ctrl.phase) { - // Command phase - case BUS::command: - ctrl.cmd[ctrl.offset] = data; -#if defined(DISK_LOG) - Log(Log::Normal, "Command phase $%02X", data); -#endif // DISK_LOG - - // Set the length again with the first data (offset 0) - if (ctrl.offset == 0) { - if (ctrl.cmd[0] >= 0x20) { - // 10バイトCDB - ctrl.length = 10; - } - } - break; - - // Message out phase - case BUS::msgout: - ctrl.message = data; -#if defined(DISK_LOG) - Log(Log::Normal, "Message out phase $%02X", data); -#endif // DISK_LOG - break; - - // Data out phase - case BUS::dataout: - ctrl.buffer[ctrl.offset] = (BYTE)data; - break; - - // Other (impossible) - default: - ASSERT(FALSE); - break; - } -} -#endif // RASCSI - -#ifdef RASCSI //--------------------------------------------------------------------------- // // Receive Data // //--------------------------------------------------------------------------- void FASTCALL SCSIDEV::Receive() -#else -//--------------------------------------------------------------------------- -// -// Continue receiving data -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIDEV::ReceiveNext() -#endif // RASCSI { -#ifdef RASCSI int len; -#endif // RASCSI BOOL result; int i; BYTE data; ASSERT(this); + LOGTRACE("%s",__PRETTY_FUNCTION__); + // REQ is low ASSERT(!ctrl.bus->GetREQ()); ASSERT(!ctrl.bus->GetIO()); -#ifdef RASCSI // Length != 0 if received if (ctrl.length != 0) { + LOGTRACE("%s length was != 0", __PRETTY_FUNCTION__); // Receive len = ctrl.bus->ReceiveHandShake( &ctrl.buffer[ctrl.offset], ctrl.length); // If not able to receive all, move to status phase if (len != (int)ctrl.length) { + LOGERROR("%s Not able to receive all data. Going to error",__PRETTY_FUNCTION__); Error(); return; } // Offset and Length ctrl.offset += ctrl.length; - ctrl.length = 0;; + ctrl.length = 0; return; } -#else - // Offset and Length - ASSERT(ctrl.length >= 1); - ctrl.offset++; - ctrl.length--; - - // If length!=0, set req again - if (ctrl.length != 0) { - // Signal line operated by the target - ctrl.bus->SetREQ(TRUE); - return; - } -#endif // RASCSI // Block subtraction, result initialization ctrl.blocks--; result = TRUE; // Processing after receiving data (by phase) + LOGTRACE("%s ctrl.phase: %d (%s)",__PRETTY_FUNCTION__, (int)ctrl.phase, BUS::GetPhaseStrRaw(ctrl.phase)); switch (ctrl.phase) { // Data out phase @@ -1696,10 +1779,6 @@ void FASTCALL SCSIDEV::ReceiveNext() if (ctrl.blocks != 0){ ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); -#ifndef RASCSI - // Signal line operated by the target - ctrl.bus->SetREQ(TRUE); -#endif // RASCSI return; } @@ -1707,7 +1786,6 @@ void FASTCALL SCSIDEV::ReceiveNext() switch (ctrl.phase) { // Command phase case BUS::command: -#ifdef RASCSI // Command data transfer len = 6; if (ctrl.buffer[0] >= 0x20 && ctrl.buffer[0] <= 0x7D) { @@ -1716,11 +1794,8 @@ void FASTCALL SCSIDEV::ReceiveNext() } for (i = 0; i < len; i++) { ctrl.cmd[i] = (DWORD)ctrl.buffer[i]; -#if defined(DISK_LOG) - Log(Log::Normal, "Command $%02X", ctrl.cmd[i]); -#endif // DISK_LOG + LOGTRACE("%s Command $%02X",__PRETTY_FUNCTION__, (int)ctrl.cmd[i]); } -#endif // RASCSI // Execution Phase Execute(); @@ -1734,10 +1809,7 @@ void FASTCALL SCSIDEV::ReceiveNext() ctrl.offset = 0; ctrl.length = 1; ctrl.blocks = 1; -#ifndef RASCSI - // Request message - ctrl.bus->SetREQ(TRUE); -#endif // RASCSI + return; } @@ -1750,20 +1822,14 @@ void FASTCALL SCSIDEV::ReceiveNext() // ABORT if (data == 0x06) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code ABORT $%02X", data); -#endif // DISK_LOG + LOGTRACE("Message code ABORT $%02X", (int)data); BusFree(); return; } // BUS DEVICE RESET if (data == 0x0C) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code BUS DEVICE RESET $%02X", data); -#endif // DISK_LOG + LOGTRACE("Message code BUS DEVICE RESET $%02X", (int)data); scsi.syncoffset = 0; BusFree(); return; @@ -1771,18 +1837,12 @@ void FASTCALL SCSIDEV::ReceiveNext() // IDENTIFY if (data >= 0x80) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code IDENTIFY $%02X", data); -#endif // DISK_LOG + LOGTRACE("Message code IDENTIFY $%02X", (int)data); } // Extended Message if (data == 0x01) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code EXTENDED MESSAGE $%02X", data); -#endif // DISK_LOG + LOGTRACE("Message code EXTENDED MESSAGE $%02X", (int)data); // Check only when synchronous transfer is possible if (!scsi.syncenable || scsi.msb[i + 2] != 0x01) { diff --git a/src/raspberrypi/controllers/scsidev_ctrl.h b/src/raspberrypi/controllers/scsidev_ctrl.h index f830b2d0..c5318efd 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.h +++ b/src/raspberrypi/controllers/scsidev_ctrl.h @@ -38,13 +38,74 @@ public: BYTE msb[256]; } scsi_t; + + enum scsi_message_code : BYTE { + eMsgCodeAbort = 0x06, + eMsgCodeAbortTag = 0x0D, + eMsgCodeBusDeviceReset = 0x0C, + eMsgCodeClearQueue = 0x0E, + eMsgCodeCommandComplete = 0x00, + eMsgCodeDisconnect = 0x04, + eMsgCodeIdentify = 0x80, + eMsgCodeIgnoreWideResidue = 0x23, // (Two Bytes) + eMsgCodeInitiateRecovery = 0x0F, + eMsgCodeInitiatorDetectedError = 0x05, + eMsgCodeLinkedCommandComplete = 0x0A, + eMsgCodeLinkedCommandCompleteWithFlag = 0x0B, + eMsgCodeMessageParityError = 0x09, + eMsgCodeMessageReject = 0x07, + eMsgCodeNoOperation = 0x08, + eMsgCodeHeadOfQueueTag = 0x21, + eMsgCodeOrderedQueueTag = 0x22, + eMsgCodeSimpleQueueTag = 0x20, + eMsgCodeReleaseRecovery = 0x10, + eMsgCodeRestorePointers = 0x03, + eMsgCodeSaveDataPointer = 0x02, + eMsgCodeTerminateIOProcess = 0x11, + }; + + + enum scsi_command : BYTE { + eCmdTestUnitReady = 0x00, + eCmdRezero = 0x01, + eCmdRequestSense = 0x03, + eCmdFormat = 0x04, + eCmdReassign = 0x07, + eCmdRead6 = 0x08, + eCmdRetrieveStats = 0x09, // DaynaPort specific command + eCmdWrite6 = 0x0A, + eCmdSeek6 = 0x0B, + eCmdSetIfaceMode = 0x0C, // DaynaPort specific command + eCmdSetMcastAddr = 0x0D, // DaynaPort specific command + eCmdEnableInterface = 0x0E, // DaynaPort specific command + eCmdInquiry = 0x12, + eCmdModeSelect = 0x15, + eCmdModeSense = 0x1A, + eCmdStartStop = 0x1B, + eCmdRcvDiag = 0x1C, + eCmdSendDiag = 0x1D, + eCmdRemoval = 0x1E, + eCmdReadCapacity = 0x25, + eCmdRead10 = 0x28, + eCmdWrite10 = 0x2A, + eCmdSeek10 = 0x2B, + eCmdWriteAndVerify10 = 0x2E, + eCmdVerify = 0x2F, + eCmdSynchronizeCache = 0x35, + eCmdReadDefectData10 = 0x37, + eCmdReadToc = 0x43, + eCmdPlayAudio10 = 0x45, + eCmdPlayAudioMSF = 0x47, + eCmdPlayAudioTrack = 0x48, + eCmdModeSelect10 = 0x55, + eCmdModeSense10 = 0x5A, + eCmdInvalid = 0xC2, // (SASI only/Suppress warning when using SxSI) + eCmdSasiCmdAssign = 0x0e, // This isn't used by SCSI, and can probably be removed. + }; + public: // Basic Functions -#ifdef RASCSI SCSIDEV(); -#else - SCSIDEV(Device *dev); -#endif // RASCSI // Constructor void FASTCALL Reset(); @@ -119,8 +180,16 @@ private: // GET MESSAGE(10) command void FASTCALL CmdSendMessage10(); // SEND MESSAGE(10) command + void FASTCALL CmdRetrieveStats(); + // DaynaPort specific command + void FASTCALL CmdSetIfaceMode(); + // DaynaPort specific command + void FASTCALL CmdSetMcastAddr(); + // DaynaPort specific command + void FASTCALL CmdEnableInterface(); + // DaynaPort specific command - // データ転送 + // Data transfer void FASTCALL Send(); // Send data #ifndef RASCSI diff --git a/src/raspberrypi/devices/ctapdriver.cpp b/src/raspberrypi/devices/ctapdriver.cpp index e06e3eb0..fd5c941c 100644 --- a/src/raspberrypi/devices/ctapdriver.cpp +++ b/src/raspberrypi/devices/ctapdriver.cpp @@ -5,16 +5,19 @@ // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS +// Copyright (C) akuker // -// Imported NetBSD support and some optimisation patch by Rin Okuyama. +// Imported NetBSD support and some optimisation patches by Rin Okuyama. // // [ TAP Driver ] // //--------------------------------------------------------------------------- +#include // For crc32() #include "os.h" #include "xm6.h" #include "ctapdriver.h" +#include "log.h" //--------------------------------------------------------------------------- // @@ -23,6 +26,7 @@ //--------------------------------------------------------------------------- CTapDriver::CTapDriver() { + LOGTRACE("%s",__PRETTY_FUNCTION__); // Initialization m_hTAP = -1; memset(&m_MacAddr, 0, sizeof(m_MacAddr)); @@ -36,6 +40,8 @@ CTapDriver::CTapDriver() #ifdef __linux__ BOOL FASTCALL CTapDriver::Init() { + LOGTRACE("%s",__PRETTY_FUNCTION__); + char dev[IFNAMSIZ] = "ras0"; struct ifreq ifr; int ret; @@ -44,7 +50,7 @@ BOOL FASTCALL CTapDriver::Init() // TAP device initilization if ((m_hTAP = open("/dev/net/tun", O_RDWR)) < 0) { - printf("Error: can't open tun\n"); + LOGERROR("Error: can't open tun. Errno: %d %s", errno, strerror(errno)); return FALSE; } @@ -53,21 +59,28 @@ BOOL FASTCALL CTapDriver::Init() ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy(ifr.ifr_name, dev, IFNAMSIZ); if ((ret = ioctl(m_hTAP, TUNSETIFF, (void *)&ifr)) < 0) { - printf("Error: can't ioctl TUNSETIFF\n"); + LOGERROR("Error: can't ioctl TUNSETIFF. Errno: %d %s", errno, strerror(errno)); close(m_hTAP); return FALSE; } + // Force the tap interface up + LOGDEBUG("ip link set ras0 up"); + system("ip link set ras0 up"); + LOGDEBUG("brctl addif rascsi_bridge ras0"); + system("brctl addif rascsi_bridge ras0"); + // Get MAC address ifr.ifr_addr.sa_family = AF_INET; if ((ret = ioctl(m_hTAP, SIOCGIFHWADDR, &ifr)) < 0) { - printf("Error: can't ioctl SIOCGIFHWADDR\n"); + LOGERROR("Error: can't ioctl SIOCGIFHWADDR. Errno: %d %s", errno, strerror(errno)); close(m_hTAP); return FALSE; } // Save MAC address memcpy(m_MacAddr, ifr.ifr_hwaddr.sa_data, sizeof(m_MacAddr)); + LOGINFO("Tap device %s created", ifr.ifr_name); return TRUE; } #endif // __linux__ @@ -82,20 +95,20 @@ BOOL FASTCALL CTapDriver::Init() // TAP Device Initialization if ((m_hTAP = open("/dev/tap", O_RDWR)) < 0) { - printf("Error: can't open tap\n"); + LOGERROR("Error: can't open tap. Errno: %d %s", errno, strerror(errno)); return FALSE; } // Get device name if (ioctl(m_hTAP, TAPGIFNAME, (void *)&ifr) < 0) { - printf("Error: can't ioctl TAPGIFNAME\n"); + LOGERROR("Error: can't ioctl TAPGIFNAME. Errno: %d %s", errno, strerror(errno)); close(m_hTAP); return FALSE; } // Get MAC address if (getifaddrs(&ifa) == -1) { - printf("Error: can't getifaddrs\n"); + LOGERROR("Error: can't getifaddrs. Errno: %d %s", errno, strerror(errno)); close(m_hTAP); return FALSE; } @@ -104,7 +117,7 @@ BOOL FASTCALL CTapDriver::Init() a->ifa_addr->sa_family == AF_LINK) break; if (a == NULL) { - printf("Error: can't get MAC address\n"); + LOGERROR("Error: can't get MAC addressErrno: %d %s", errno, strerror(errno)); close(m_hTAP); return FALSE; } @@ -114,7 +127,7 @@ BOOL FASTCALL CTapDriver::Init() sizeof(m_MacAddr)); freeifaddrs(ifa); - printf("Tap device : %s\n", ifr.ifr_name); + LOGINFO("Tap device : %s\n", ifr.ifr_name); return TRUE; } @@ -129,11 +142,56 @@ void FASTCALL CTapDriver::Cleanup() { ASSERT(this); - // TAPデバイス解放 + + LOGDEBUG("brctl delif rascsi_bridge ras0"); + system("brctl delif rascsi_bridge ras0"); + + + // Release TAP device if (m_hTAP != -1) { close(m_hTAP); m_hTAP = -1; } + + + +} + +//--------------------------------------------------------------------------- +// +// Enable +// +//--------------------------------------------------------------------------- +BOOL FASTCALL CTapDriver::Enable(){ + int result; + LOGDEBUG("%s: ip link set ras0 up", __PRETTY_FUNCTION__); + result = system("ip link set ras0 up"); + return (result == EXIT_SUCCESS); +} + +//--------------------------------------------------------------------------- +// +// Disable +// +//--------------------------------------------------------------------------- +BOOL FASTCALL CTapDriver::Disable(){ + int result; + LOGDEBUG("%s: ip link set ras0 down", __PRETTY_FUNCTION__); + result = system("ip link set ras0 down"); + return (result == EXIT_SUCCESS); +} + +//--------------------------------------------------------------------------- +// +// Flush +// +//--------------------------------------------------------------------------- +BOOL FASTCALL CTapDriver::Flush(){ + LOGTRACE("%s", __PRETTY_FUNCTION__); + while(PendingPackets()){ + (void)Rx(m_garbage_buffer); + } + return TRUE; } //--------------------------------------------------------------------------- @@ -154,10 +212,9 @@ void FASTCALL CTapDriver::GetMacAddr(BYTE *mac) // Receive // //--------------------------------------------------------------------------- -int FASTCALL CTapDriver::Rx(BYTE *buf) +BOOL FASTCALL CTapDriver::PendingPackets() { struct pollfd fds; - DWORD dwReceived; ASSERT(this); ASSERT(m_hTAP != -1); @@ -167,7 +224,29 @@ int FASTCALL CTapDriver::Rx(BYTE *buf) fds.events = POLLIN | POLLERR; fds.revents = 0; poll(&fds, 1, 0); + LOGTRACE("%s %u revents", __PRETTY_FUNCTION__, fds.revents); if (!(fds.revents & POLLIN)) { + return FALSE; + }else { + return TRUE; + } +} + +//--------------------------------------------------------------------------- +// +// Receive +// +//--------------------------------------------------------------------------- +int FASTCALL CTapDriver::Rx(BYTE *buf) +{ + DWORD dwReceived; + DWORD crc; + + ASSERT(this); + ASSERT(m_hTAP != -1); + + // Check if there is data that can be received + if(!PendingPackets()){ return 0; } @@ -179,14 +258,23 @@ int FASTCALL CTapDriver::Rx(BYTE *buf) // If reception is enabled if (dwReceived > 0) { - // Pad to the maximum frame size (60 bytes) excluding FCS - if (dwReceived < 60) { - memset(buf + dwReceived, 0, 60 - dwReceived); - dwReceived = 60; - } + // We need to add the Frame Check Status (FCS) CRC back onto the end of the packet. + // The Linux network subsystem removes it, since most software apps shouldn't ever + // need it. - // Add a dummy FCS - memset(buf + dwReceived, 0, 4); + // Initialize the CRC + crc = crc32(0L, Z_NULL, 0); + // Calculate the CRC + crc = crc32(crc, buf, dwReceived); + + buf[dwReceived + 0] = (BYTE)((crc >> 0) & 0xFF); + buf[dwReceived + 1] = (BYTE)((crc >> 8) & 0xFF); + buf[dwReceived + 2] = (BYTE)((crc >> 16) & 0xFF); + buf[dwReceived + 3] = (BYTE)((crc >> 24) & 0xFF); + + LOGDEBUG("%s CRC is %08lX - %02X %02X %02X %02X\n", __PRETTY_FUNCTION__, crc, buf[dwReceived+0], buf[dwReceived+1], buf[dwReceived+2], buf[dwReceived+3]); + + // Add FCS size to the received message size dwReceived += 4; } @@ -199,7 +287,7 @@ int FASTCALL CTapDriver::Rx(BYTE *buf) // Send // //--------------------------------------------------------------------------- -int FASTCALL CTapDriver::Tx(BYTE *buf, int len) +int FASTCALL CTapDriver::Tx(const BYTE *buf, int len) { ASSERT(this); ASSERT(m_hTAP != -1); diff --git a/src/raspberrypi/devices/ctapdriver.h b/src/raspberrypi/devices/ctapdriver.h index 68dffe66..02fb5695 100644 --- a/src/raspberrypi/devices/ctapdriver.h +++ b/src/raspberrypi/devices/ctapdriver.h @@ -5,6 +5,7 @@ // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS +// Copyright (C) akuker // // Imported NetBSD support and some optimisation patch by Rin Okuyama. // @@ -38,8 +39,16 @@ public: // Get Mac Address int FASTCALL Rx(BYTE *buf); // Receive - int FASTCALL Tx(BYTE *buf, int len); + int FASTCALL Tx(const BYTE *buf, int len); // Send + BOOL FASTCALL PendingPackets(); + // Check if there are IP packets available + BOOL FASTCALL Enable(); + // Enable the ras0 interface + BOOL FASTCALL Disable(); + // Disable the ras0 interface + BOOL FASTCALL Flush(); + // Purge all of the packets that are waiting to be processed private: BYTE m_MacAddr[6]; @@ -48,6 +57,7 @@ private: // Send Valid Flag int m_hTAP; // File handle + BYTE m_garbage_buffer[ETH_FRAME_LEN]; }; #endif // ctapdriver_h diff --git a/src/raspberrypi/devices/disk.cpp b/src/raspberrypi/devices/disk.cpp index a05f27ac..e97142ed 100644 --- a/src/raspberrypi/devices/disk.cpp +++ b/src/raspberrypi/devices/disk.cpp @@ -357,6 +357,7 @@ BOOL FASTCALL DiskTrack::Read(BYTE *buf, int sec) const ASSERT(buf); ASSERT((sec >= 0) & (sec < 0x100)); + LOGTRACE("%s reading sector: %d", __PRETTY_FUNCTION__,sec); // Error if not initialized if (!dt.init) { return FALSE; @@ -973,6 +974,15 @@ BOOL FASTCALL Disk::IsNULL() const } return FALSE; } +//--------------------------------------------------------------------------- +// +// Retrieve the disk's ID +// +//--------------------------------------------------------------------------- +DWORD FASTCALL Disk::GetID() const +{ + return disk.id; +} //--------------------------------------------------------------------------- // @@ -1162,6 +1172,7 @@ BOOL FASTCALL Disk::CheckReady() if (disk.reset) { disk.code = DISK_DEVRESET; disk.reset = FALSE; + LOGTRACE("%s Disk in reset", __PRETTY_FUNCTION__); return FALSE; } @@ -1169,17 +1180,21 @@ BOOL FASTCALL Disk::CheckReady() if (disk.attn) { disk.code = DISK_ATTENTION; disk.attn = FALSE; + LOGTRACE("%s Disk in needs attention", __PRETTY_FUNCTION__); return FALSE; } // Return status if not ready if (!disk.ready) { disk.code = DISK_NOTREADY; + LOGTRACE("%s Disk not ready", __PRETTY_FUNCTION__); return FALSE; } // Initialization with no error disk.code = DISK_NOERROR; + LOGTRACE("%s Disk is ready!", __PRETTY_FUNCTION__); + return TRUE; } @@ -1222,6 +1237,7 @@ int FASTCALL Disk::RequestSense(const DWORD *cdb, BYTE *buf) // Size determination (according to allocation length) size = (int)cdb[4]; + LOGTRACE("%s size of data = %d", __PRETTY_FUNCTION__, size); ASSERT((size >= 0) && (size < 0x100)); // For SCSI-1, transfer 4 bytes when the size is 0 @@ -1966,7 +1982,7 @@ BOOL FASTCALL Disk::Reassign(const DWORD* /*cdb*/) // READ // //--------------------------------------------------------------------------- -int FASTCALL Disk::Read(BYTE *buf, DWORD block) +int FASTCALL Disk::Read(const DWORD *cdb, BYTE *buf, DWORD block) { ASSERT(this); ASSERT(buf); @@ -2026,11 +2042,12 @@ int FASTCALL Disk::WriteCheck(DWORD block) // WRITE // //--------------------------------------------------------------------------- -BOOL FASTCALL Disk::Write(const BYTE *buf, DWORD block) +BOOL FASTCALL Disk::Write(const DWORD *cdb, const BYTE *buf, DWORD block) { ASSERT(this); ASSERT(buf); + LOGTRACE("%s", __PRETTY_FUNCTION__); // Error if not ready if (!disk.ready) { disk.code = DISK_NOTREADY; diff --git a/src/raspberrypi/devices/disk.h b/src/raspberrypi/devices/disk.h index 725880fb..ae9e5de9 100644 --- a/src/raspberrypi/devices/disk.h +++ b/src/raspberrypi/devices/disk.h @@ -233,7 +233,7 @@ public: #endif // RASCSI // ID - DWORD FASTCALL GetID() const { return disk.id; } + DWORD FASTCALL GetID() const; // Get media ID BOOL FASTCALL IsNULL() const; // NULL check @@ -298,11 +298,11 @@ public: // FORMAT UNIT command BOOL FASTCALL Reassign(const DWORD *cdb); // REASSIGN UNIT command - virtual int FASTCALL Read(BYTE *buf, DWORD block); + virtual int FASTCALL Read(const DWORD *cdb, BYTE *buf, DWORD block); // READ command - int FASTCALL WriteCheck(DWORD block); + virtual int FASTCALL WriteCheck(DWORD block); // WRITE check - BOOL FASTCALL Write(const BYTE *buf, DWORD block); + virtual BOOL FASTCALL Write(const DWORD *cdb, const BYTE *buf, DWORD block); // WRITE command BOOL FASTCALL Seek(const DWORD *cdb); // SEEK command diff --git a/src/raspberrypi/devices/scsi_daynaport.cpp b/src/raspberrypi/devices/scsi_daynaport.cpp new file mode 100644 index 00000000..ff8ec5f6 --- /dev/null +++ b/src/raspberrypi/devices/scsi_daynaport.cpp @@ -0,0 +1,544 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI (*^..^*) +// for Raspberry Pi +// +// Copyright (C) 2020 akuker +// Copyright (C) 2014-2020 GIMONS +// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) +// +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. +// +// [ Emulation of the DaynaPort SCSI Link Ethernet interface ] +// +// This design is derived from the SLINKCMD.TXT file, as well as David Kuder's +// Tiny SCSI Emulator +// - SLINKCMD: http://www.bitsavers.org/pdf/apple/scsi/dayna/daynaPORT/SLINKCMD.TXT +// - Tiny SCSI : https://hackaday.io/project/18974-tiny-scsi-emulator +// +// This does NOT include the file system functionality that is present +// in the Sharp X68000 host bridge. +// +// Note: This requires the DaynaPort SCSI Link driver. +//--------------------------------------------------------------------------- + +#include "scsi_daynaport.h" + +//=========================================================================== +// +// DaynaPort SCSI Link Ethernet Adapter +// +//=========================================================================== +const char* SCSIDaynaPort::m_vendor_name = "DAYNA "; +const char* SCSIDaynaPort::m_device_name = "SCSI/Link "; +const char* SCSIDaynaPort::m_revision = "1.4a"; +const char* SCSIDaynaPort::m_firmware_version = "01.00.00"; + +const BYTE SCSIDaynaPort::m_bcast_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +const BYTE SCSIDaynaPort::m_apple_talk_addr[6] = { 0x09, 0x00, 0x07, 0xff, 0xff, 0xff }; + +#ifndef NDEBUG +static DWORD file_counter = 0; +#endif + +//--------------------------------------------------------------------------- +// +// Constructor +// +//--------------------------------------------------------------------------- +SCSIDaynaPort::SCSIDaynaPort() : Disk() +{ + LOGTRACE("SCSI DaynaPort Constructor"); + // DaynaPort + disk.id = MAKEID('S', 'C', 'D', 'P'); + +#if defined(__linux__) && !defined(BAREMETAL) + // TAP Driver Generation + m_tap = new CTapDriver(); + m_bTapEnable = m_tap->Init(); + if(!m_bTapEnable){ + LOGERROR("Unable to open the TAP interface"); + }else { + LOGINFO("Tap interface created") + } + + this->Reset(); + disk.ready = true; + disk.reset = false; + + // Generate MAC Address + memset(m_mac_addr, 0x00, 6); + + // if (m_bTapEnable) { + // tap->GetMacAddr(m_mac_addr); + // m_mac_addr[5]++; + // } + // !!!!!!!!!!!!!!!!! For now, hard code the MAC address. Its annoying when it keeps changing during development! + // TODO: Remove this hard-coded address + m_mac_addr[0]=0x00; + m_mac_addr[1]=0x80; + m_mac_addr[2]=0x19; + m_mac_addr[3]=0x10; + m_mac_addr[4]=0x98; + m_mac_addr[5]=0xE3; + +#endif // RASCSI && !BAREMETAL + LOGTRACE("SCSIDaynaPort Constructor End"); + +} + +//--------------------------------------------------------------------------- +// +// Destructor +// +//--------------------------------------------------------------------------- +SCSIDaynaPort::~SCSIDaynaPort() +{ + LOGTRACE("SCSIDaynaPort Destructor"); + // TAP driver release + if (m_tap) { + m_tap->Cleanup(); + delete m_tap; + } +} + +//--------------------------------------------------------------------------- +// +// INQUIRY +// +//--------------------------------------------------------------------------- +int FASTCALL SCSIDaynaPort::Inquiry( + const DWORD *cdb, BYTE *buffer, DWORD major, DWORD minor) +{ + DWORD allocation_length; + // scsi_cdb_6_byte_t command; + // memcpy(&command,cdb,sizeof(command)); + + ASSERT(this); + ASSERT(cdb); + ASSERT(buffer); + ASSERT(cdb[0] == 0x12); + + //allocation_length = command->length; + allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8); + // if(allocation_length != command.length){ + // LOGDEBUG("%s CDB: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__, (unsigned int)cdb[0], (unsigned int)cdb[1], (unsigned int)cdb[2], (unsigned int)cdb[3], (unsigned int)cdb[4], (unsigned int)cdb[5] ); + // LOGWARN(":::::::::: Expected allocation length %04X but found %04X", (unsigned int)allocation_length, (unsigned int)command.length); + // LOGWARN(":::::::::: Doing runtime pointer conversion: %04X", ((scsi_cdb_6_byte_t*)cdb)->length); + // } + + LOGTRACE("%s Inquiry with major %ld, minor %ld. Allocaiton length: %d",__PRETTY_FUNCTION__, major, minor, (int)allocation_length); + + if(cdb[1] & 0x3) { + LOGWARN("Tiny SCSI Emulator says this is an invalid request"); + } + + if(allocation_length > 4){ + // Copy the pre-canned response + memcpy(buffer, m_target_ethernet_inquiry_response, allocation_length); + // Set the size + //buffer[4] = (BYTE)((allocation_length - 7) & 0xFF); + // The inquiry response format only allows for a 1 byte 'additional size' field + if(allocation_length > 0xFF){ + LOGWARN("%s The inquiry format only allows for a maximum of %d (0xFF + 4) bytes",\ + __PRETTY_FUNCTION__, (int)0xFF + 4) + } + } + + LOGTRACE("response size is %d", (int)allocation_length); + + // Success + disk.code = DISK_NOERROR; + return allocation_length; +} + +//--------------------------------------------------------------------------- +// +// RequestSense +// +//--------------------------------------------------------------------------- +int FASTCALL SCSIDaynaPort::RequestSense(const DWORD *cdb, BYTE *buffer) +{ + // The DaynaPort RequestSense response will always be 9 bytes. + int size = 9; + + LOGTRACE("%s size of sense data = %d", __PRETTY_FUNCTION__, size); + + // Clear the buffer + memset(buffer, 0, size); + + // Only set the response code (70h) + buffer[0] = 0x70; + + // Clear the code + disk.code = 0x00; + + return size; +} + +//--------------------------------------------------------------------------- +// +// READ +// +//--------------------------------------------------------------------------- +int FASTCALL SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, DWORD block) +{ + WORD requested_length = 0; + int rx_packet_size = 0; + BOOL send_message_to_host; + scsi_resp_read_t *response = (scsi_resp_read_t*)buf; + scsi_cmd_read_6_t *command = (scsi_cmd_read_6_t*)cdb; + int read_count = 0; + + ASSERT(this); + ASSERT(buf); + + LOGTRACE("%s reading DaynaPort block %lu", __PRETTY_FUNCTION__, block); + + if(command->operation_code != 0x08){ + LOGERROR("Received unexpected cdb command: %02X. Expected 0x08", (unsigned int)command->operation_code); + } + + requested_length = (WORD)command->transfer_length; + LOGTRACE("%s Read maximum length %d, (%04X)", __PRETTY_FUNCTION__, (unsigned int)requested_length, (unsigned int)requested_length); + + + // At host startup, it will send a READ(6) command with a length of 1. We should + // respond by going into the status mode with a code of 0x02 + if(requested_length == 1){ + return 0; + } + + // Some of the packets we receive will not be for us. So, we'll keep pulling messages + // until the buffer is empty, or we've read X times. (X is just a made up number) + while(read_count < 50) + { + read_count++; + + // The first 2 bytes are reserved for the length of the packet + // The next 4 bytes are reserved for a flag field + //rx_packet_size = m_tap->Rx(response->data); + rx_packet_size = m_tap->Rx(&buf[m_read_header_size]); + + // If we didn't receive anything, return size of 0 + if(rx_packet_size <= 0){ + LOGTRACE("%s No packet received", __PRETTY_FUNCTION__); + response->length = 0; + response->flags = e_no_more_data; + return m_read_header_size; + } + + LOGTRACE("%s Packet Sz %d (%08X) read: %d", __PRETTY_FUNCTION__, (unsigned int) rx_packet_size, (unsigned int) rx_packet_size, read_count); + + // This is a very basic filter to prevent unnecessary packets from + // being sent to the SCSI initiator. + send_message_to_host = FALSE; + + // Check if received packet destination MAC address matches the + // DaynaPort MAC. For IP packets, the mac_address will be the first 6 bytes + // of the data. + if (memcmp(response->data, m_mac_addr, 6) == 0) { + send_message_to_host = TRUE; + } + + // Check to see if this is a broadcast message + if (memcmp(response->data, m_bcast_addr, 6) == 0) { + send_message_to_host = TRUE; + } + + // Check to see if this is an AppleTalk Message + if (memcmp(response->data, m_apple_talk_addr, 6) == 0) { + + send_message_to_host = TRUE; + } + + // TODO: We should check to see if this message is in the multicast + // configuration from SCSI command 0x0D + + if(!send_message_to_host){ + LOGDEBUG("%s Received a packet that's not for me: %02X %02X %02X %02X %02X %02X", \ + __PRETTY_FUNCTION__, + (int)response->data[0], + (int)response->data[1], + (int)response->data[2], + (int)response->data[3], + (int)response->data[4], + (int)response->data[5]); + + // If there are pending packets to be processed, we'll tell the host that the read + // length was 0. + if(!m_tap->PendingPackets()) + { + response->length = 0; + response->flags = e_no_more_data; + return m_read_header_size; + } + } + else + { + + // TODO: Need to do some sort of size checking. The buffer can easily overflow, probably. + + + // response->length = rx_packet_size; + // if(m_tap->PendingPackets()){ + // response->flags = e_more_data_available; + // } else { + // response->flags = e_no_more_data; + // } + buf[0] = (BYTE)((rx_packet_size >> 8) & 0xFF); + buf[1] = (BYTE)(rx_packet_size & 0xFF); + + buf[2] = 0; + buf[3] = 0; + buf[4] = 0; + if(m_tap->PendingPackets()){ + buf[5] = 0x10; + } else { + buf[5] = 0; + } + + LOGTRACE("%s Packet of size %d received [Counter: %d]", __PRETTY_FUNCTION__, (int)rx_packet_size, (int)file_counter); + + // Return the packet size + 2 for the length + 4 for the flag field + // The CRC was already appended by the ctapdriver + return rx_packet_size + m_read_header_size; + } + // If we got to this point, there are still messages in the queue, so + // we should loop back and get the next one. + } // end while + + response->length = 0; + response->flags = e_no_more_data; + return m_read_header_size; +} + +//--------------------------------------------------------------------------- +// +// WRITE check +// +//--------------------------------------------------------------------------- +int FASTCALL SCSIDaynaPort::WriteCheck(DWORD block) +{ + LOGTRACE("%s block: %lu", __PRETTY_FUNCTION__, block); + + // Status check + if (!CheckReady()) { + return 0; + } + + if(!m_bTapEnable){ + disk.code = DISK_NOTREADY; + return 0; + } + + // Success + return 1; +} + + +//--------------------------------------------------------------------------- +// +// Write +// +//--------------------------------------------------------------------------- +BOOL FASTCALL SCSIDaynaPort::Write(const DWORD *cdb, const BYTE *buf, DWORD block) +{ + BYTE data_format; + WORD data_length; + // const scsi_cmd_daynaport_write_t* command = (const scsi_cmd_daynaport_write_t*)cdb; + + data_format = cdb[5]; + data_length = (WORD)cdb[4] + ((WORD)cdb[3] << 8); + + // if(data_format != command->format){ + // LOGDEBUG("%s CDB: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__, (unsigned int)cdb[0], (unsigned int)cdb[1], (unsigned int)cdb[2], (unsigned int)cdb[3], (unsigned int)cdb[4], (unsigned int)cdb[5] ); + // LOGWARN("Expected data_format: %02X, but found %02X", (unsigned int)cdb[5], (unsigned int)command->format); + // } + // if(data_length != command->length){ + // LOGDEBUG("%s CDB: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__, (unsigned int)cdb[0], (unsigned int)cdb[1], (unsigned int)cdb[2], (unsigned int)cdb[3], (unsigned int)cdb[4], (unsigned int)cdb[5] ); + // LOGWARN("Expected data_length: %04X, but found %04X", data_length, (unsigned int)command->length); + // } + + if(data_format == 0x00){ + m_tap->Tx(buf, data_length); + LOGTRACE("%s Transmitted %u bytes (00 format)", __PRETTY_FUNCTION__, data_length); + return TRUE; + } + else if (data_format == 0x80){ + // The data length is actuall specified in the first 2 bytes of the payload + data_length=(WORD)buf[1] + ((WORD)buf[0] << 8); + m_tap->Tx(&buf[4], data_length); + LOGTRACE("%s Transmitted %u bytes (80 format)", __PRETTY_FUNCTION__, data_length); + return TRUE; + } + else + { + // LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)command->format); + LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)data_format); + return FALSE; + } + +} + + +//--------------------------------------------------------------------------- +// +// RetrieveStats +// +//--------------------------------------------------------------------------- +int FASTCALL SCSIDaynaPort::RetrieveStats(const DWORD *cdb, BYTE *buffer) +{ + DWORD response_size; + DWORD allocation_length; + + // DWORD frame_alignment_errors; + // DWORD crc_errors; + // DWORD frames_lost; + + LOGTRACE("%s RetrieveStats ", __PRETTY_FUNCTION__); + + ASSERT(this); + ASSERT(cdb); + ASSERT(buffer); + + allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8); + LOGTRACE("%s Retrieve Stats buffer size was %d", __PRETTY_FUNCTION__, (int)allocation_length); + + // // ASSERT(cdb[0] == 0x09); + + // if(cdb[0] != 0x09) + // { + // LOGWARN("%s cdb[0] was not 0x09, as I expected. It was %02X.", __PRETTY_FUNCTION__, (unsigned int)cdb[0]); + // } + // if(cdb[4] != 0x12) + // { + // LOGWARN("%s cdb[4] was not 0x12, as I expected. It was %02X.", __PRETTY_FUNCTION__, (unsigned int)cdb[4]); + // } + + // memset(buffer,0,18); + + // memcpy(&buffer[0],m_mac_addr,sizeof(m_mac_addr)); + // // frame alignment errors + // frame_alignment_errors = htonl(0); + // memcpy(&(buffer[6]),&frame_alignment_errors,sizeof(frame_alignment_errors)); + // // CRC errors + // crc_errors = htonl(0); + // memcpy(&(buffer[10]),&crc_errors,sizeof(crc_errors)); + // // frames lost + // frames_lost = htonl(0); + // memcpy(&(buffer[14]),&frames_lost,sizeof(frames_lost)); + + for(int i=0; i< 6; i++) + { + LOGINFO("%s CDB byte %d: %02X",__PRETTY_FUNCTION__, i, (unsigned int)cdb[i]); + } + + response_size = 18; + + + response_size = sizeof(m_scsi_link_stats); + memcpy(buffer, &m_scsi_link_stats, sizeof(m_scsi_link_stats)); + + LOGTRACE("%s response size is %d", __PRETTY_FUNCTION__, (int)response_size); + + // // SendMessage6 is 18 bytes + // for(int i=0; i< 18; i++) + // { + // LOGDEBUG("%s Byte %d: %02X",__PRETTY_FUNCTION__, i, (int)buffer[i]); + // } + if(response_size > allocation_length) + { + response_size = allocation_length; + LOGINFO("%s Truncating the inquiry response", __PRETTY_FUNCTION__) + } + + // Success + disk.code = DISK_NOERROR; + return response_size; + // scsi_cdb_6_byte_t *command = (scsi_cdb_6_byte_t*)cdb; + // scsi_resp_link_stats_t *response = (scsi_resp_link_stats_t*) buffer; + + // LOGTRACE("%s Retrieve Stats buffer size was %d", __PRETTY_FUNCTION__, command->length); + + // ASSERT(sizeof(scsi_resp_link_stats_t) == 18); + + // memcpy(response->mac_address, m_mac_addr, sizeof(m_mac_addr)); + // response->crc_errors = 0; + // response->frames_lost = 0; + // response->frame_alignment_errors = 0; + + // // Success + // disk.code = DISK_NOERROR; + // return sizeof(scsi_resp_link_stats_t); +} + +//--------------------------------------------------------------------------- +// +// Enable or Disable the interface +// +//--------------------------------------------------------------------------- +BOOL FASTCALL SCSIDaynaPort::EnableInterface(const DWORD *cdb) +{ + int result; + // scsi_cdb_6_byte_t *command = (scsi_cdb_6_byte_t*)cdb; + + // if(command->control & 0x80) + if(cdb[5] & 0x80) + + { + result = m_tap->Enable(); + if(result){ + LOGINFO("The DaynaPort interface has been ENABLED."); + } + else{ + LOGWARN("Unable to enable the DaynaPort Interface"); + } + m_tap->Flush(); + } + else + { + result = m_tap->Disable(); + if(result){ + LOGINFO("The DaynaPort interface has been DISABLED."); + } + else{ + LOGWARN("Unable to disable the DaynaPort Interface"); + } + } + + return TRUE; +} + +//--------------------------------------------------------------------------- +// +// TEST UNIT READY +// +//--------------------------------------------------------------------------- +BOOL FASTCALL SCSIDaynaPort::TestUnitReady(const DWORD* /*cdb*/) +{ + ASSERT(this); + LOGTRACE("%s", __PRETTY_FUNCTION__); + + // TEST UNIT READY Success + disk.code = DISK_NOERROR; + return TRUE; +} + +//--------------------------------------------------------------------------- +// +// Set Mode - enable broadcast messages +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDaynaPort::SetMode(const DWORD *cdb, BYTE *buffer) +{ + LOGTRACE("%s Setting mode", __PRETTY_FUNCTION__); + + for(size_t i=0; i= 0); - return Disk::Read(buf, block); + return Disk::Read(cdb, buf, block); } //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/devices/scsicd.h b/src/raspberrypi/devices/scsicd.h index ca4b9070..2ccd9b52 100644 --- a/src/raspberrypi/devices/scsicd.h +++ b/src/raspberrypi/devices/scsicd.h @@ -122,7 +122,7 @@ private: // Wave path BOOL valid; // Open result (is it valid?) - DWORD *buf; + DWORD *m_buf; // Data buffer DWORD read; // Read pointer @@ -164,7 +164,7 @@ public: // commands int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command - int FASTCALL Read(BYTE *buf, DWORD block); + int FASTCALL Read(const DWORD *cdb, BYTE *buf, DWORD block) override; // READ command int FASTCALL ReadToc(const DWORD *cdb, BYTE *buf); // READ TOC command diff --git a/src/raspberrypi/devices/scsihd.cpp b/src/raspberrypi/devices/scsihd.cpp index ed4c32b1..cc9fa858 100644 --- a/src/raspberrypi/devices/scsihd.cpp +++ b/src/raspberrypi/devices/scsihd.cpp @@ -100,7 +100,7 @@ BOOL FASTCALL SCSIHD::Open(const Filepath& path, BOOL /*attn*/) // INQUIRY // //--------------------------------------------------------------------------- -int FASTCALL SCSIHD::Inquiry( +int FASTCALL SCSIHD:: Inquiry( const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor) { char vendor[32]; diff --git a/src/raspberrypi/gpiobus.h b/src/raspberrypi/gpiobus.h index 0bce816b..943e3f5b 100644 --- a/src/raspberrypi/gpiobus.h +++ b/src/raspberrypi/gpiobus.h @@ -433,6 +433,30 @@ // //--------------------------------------------------------------------------- #define GPIO_DATA_SETTLING 100 // Data bus stabilization time (ns) +// SCSI Bus timings taken from: +// https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-05.html +#define SCSI_DELAY_ARBITRATION_DELAY_NS 2400 +#define SCSI_DELAY_ASSERTION_PERIOD_NS 90 +#define SCSI_DELAY_BUS_CLEAR_DELAY_NS 800 +#define SCSI_DELAY_BUS_FREE_DELAY_NS 800 +#define SCSI_DELAY_BUS_SET_DELAY_NS 1800 +#define SCSI_DELAY_BUS_SETTLE_DELAY_NS 400 +#define SCSI_DELAY_CABLE_SKEW_DELAY_NS 10 +#define SCSI_DELAY_DATA_RELEASE_DELAY_NS 400 +#define SCSI_DELAY_DESKEW_DELAY_NS 45 +#define SCSI_DELAY_DISCONNECTION_DELAY_US 200 +#define SCSI_DELAY_HOLD_TIME_NS 45 +#define SCSI_DELAY_NEGATION_PERIOD_NS 90 +#define SCSI_DELAY_POWER_ON_TO_SELECTION_TIME_S 10 // (recommended) +#define SCSI_DELAY_RESET_TO_SELECTION_TIME_US (250*1000) // (recommended) +#define SCSI_DELAY_RESET_HOLD_TIME_US 25 +#define SCSI_DELAY_SELECTION_ABORT_TIME_US 200 +#define SCSI_DELAY_SELECTION_TIMEOUT_DELAY_NS (250*1000) // (recommended) +#define SCSI_DELAY_FAST_ASSERTION_PERIOD_NS 30 +#define SCSI_DELAY_FAST_CABLE_SKEW_DELAY_NS 5 +#define SCSI_DELAY_FAST_DESKEW_DELAY_NS 20 +#define SCSI_DELAY_FAST_HOLD_TIME_NS 10 +#define SCSI_DELAY_FAST_NEGATION_PERIOD_NS 30 //--------------------------------------------------------------------------- // @@ -544,7 +568,7 @@ public: // Data transmission handshake static BUS::phase_t FASTCALL GetPhaseRaw(DWORD raw_data); - // Get the phase based on raw data + // Get the phase based on raw data #ifdef USE_SEL_EVENT_ENABLE // SEL signal interrupt diff --git a/src/raspberrypi/launch_sudo.sh b/src/raspberrypi/launch_sudo.sh new file mode 100755 index 00000000..6ce283c1 --- /dev/null +++ b/src/raspberrypi/launch_sudo.sh @@ -0,0 +1,3 @@ +# This is used for debugging. VisualStudio code will call this file when launching +# the debugger, instead of directly calling GDB. That way we can add the pkexec +sudo /usr/bin/gdb "$@" \ No newline at end of file diff --git a/src/raspberrypi/log.h b/src/raspberrypi/log.h index 79882b75..0a5de651 100644 --- a/src/raspberrypi/log.h +++ b/src/raspberrypi/log.h @@ -16,40 +16,26 @@ #include "spdlog/spdlog.h" #include "spdlog/sinks/sink.h" -#define SPDLOGWRAPPER(loglevel, ...)\ - do{ char buf[256]; \ - snprintf(buf, sizeof(buf),__VA_ARGS__); \ - spdlog::log(loglevel,buf);}while(0); +#define SPDLOGWRAPPER(loglevel, ...) \ +do \ +{ \ + char logbuf[256]; \ + snprintf(logbuf, sizeof(logbuf), __VA_ARGS__); \ + spdlog::log(loglevel, logbuf); \ +} while (0); -#ifndef DEBUG +#ifdef NDEBUG // If we're doing a non-debug build, we want to skip the overhead of // formatting the string, then calling the logger -#define LOGTRACE(...) ((void)0) -#define LOGDEBUG(...) ((void)0) +#define LOGTRACE(...) ((void)0) +#define LOGDEBUG(...) ((void)0) #else -#define LOGTRACE(...) SPDLOGWRAPPER(spdlog::level::trace, __VA_ARGS__) -#define LOGDEBUG(...) SPDLOGWRAPPER(spdlog::level::debug, __VA_ARGS__) +#define LOGTRACE(...) SPDLOGWRAPPER(spdlog::level::trace, __VA_ARGS__) +#define LOGDEBUG(...) SPDLOGWRAPPER(spdlog::level::debug, __VA_ARGS__) #endif -#define LOGINFO(...) SPDLOGWRAPPER(spdlog::level::info, __VA_ARGS__) -#define LOGWARN(...) SPDLOGWRAPPER(spdlog::level::warn, __VA_ARGS__) -#define LOGERROR(...) SPDLOGWRAPPER(spdlog::level::err, __VA_ARGS__) -#define LOGCRITICAL(...) SPDLOGWRAPPER(spdlog::level::critical, __VA_ARGS__) +#define LOGINFO(...) SPDLOGWRAPPER(spdlog::level::info, __VA_ARGS__) +#define LOGWARN(...) SPDLOGWRAPPER(spdlog::level::warn, __VA_ARGS__) +#define LOGERROR(...) SPDLOGWRAPPER(spdlog::level::err, __VA_ARGS__) +#define LOGCRITICAL(...) SPDLOGWRAPPER(spdlog::level::critical, __VA_ARGS__) - -//=========================================================================== -// -// ログ -// -//=========================================================================== -class Log -{ -public: - enum loglevel { - Detail, // 詳細レベル - Normal, // 通常レベル - Warning, // 警告レベル - Debug // デバッグレベル - }; -}; - -#endif // log_h +#endif // log_h diff --git a/src/raspberrypi/os.h b/src/raspberrypi/os.h index e1da949e..cb145f7e 100644 --- a/src/raspberrypi/os.h +++ b/src/raspberrypi/os.h @@ -5,10 +5,11 @@ // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS +// Copyright (C) 2020 akuker // // Imported NetBSD support and some optimisation patch by Rin Okuyama. // -// [ OS固有 ] +// [ OS related definitions ] // //--------------------------------------------------------------------------- @@ -86,7 +87,7 @@ //--------------------------------------------------------------------------- // -// 基本マクロ +// Basic Macros // //--------------------------------------------------------------------------- #undef FASTCALL @@ -118,7 +119,7 @@ //--------------------------------------------------------------------------- // -// 基本型定義 +// Basic Type Definitions // //--------------------------------------------------------------------------- typedef unsigned char BYTE; diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index 8fc44ae1..331359a3 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -21,10 +21,12 @@ #include "devices/scsicd.h" #include "devices/scsimo.h" #include "devices/scsi_host_bridge.h" +#include "devices/scsi_daynaport.h" #include "controllers/scsidev_ctrl.h" #include "controllers/sasidev_ctrl.h" #include "gpiobus.h" #include "rascsi_version.h" +#include "rasctl.h" #include "spdlog/spdlog.h" //--------------------------------------------------------------------------- @@ -95,7 +97,7 @@ void Banner(int argc, char* argv[]) FPRT(stdout," FILE is disk image file.\n\n"); FPRT(stdout,"Usage: %s [-HDn FILE] ...\n\n", argv[0]); FPRT(stdout," n is X68000 SASI HD number(0-15).\n"); - FPRT(stdout," FILE is disk image file.\n\n"); + FPRT(stdout," FILE is disk image file, \"daynaport\", or \"bridge\".\n\n"); FPRT(stdout," Image type is detected based on file extension.\n"); FPRT(stdout," hdf : SASI HD image(XM6 SASI HD image)\n"); FPRT(stdout," hds : SCSI HD image(XM6 SCSI HD image)\n"); @@ -468,7 +470,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) // Distinguish between SASI and SCSI ext = NULL; pUnit = NULL; - if (type == 0) { + if (type == rasctl_dev_sasi_hd) { // Passed the check if (!file) { return FALSE; @@ -488,16 +490,16 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) // If the extension is not SASI type, replace with SCSI ext = &file[len - 3]; if (xstrcasecmp(ext, "hdf") != 0) { - type = 1; + type = rasctl_dev_scsi_hd; } } // Create a new drive, based upon type switch (type) { - case 0: // HDF + case rasctl_dev_sasi_hd: // HDF pUnit = new SASIHD(); break; - case 1: // HDS/HDN/HDI/NHD/HDA + case rasctl_dev_scsi_hd: // HDS/HDN/HDI/NHD/HDA if (ext == NULL) { break; } @@ -510,15 +512,21 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) pUnit = new SCSIHD(); } break; - case 2: // MO + case rasctl_dev_mo: // MO pUnit = new SCSIMO(); break; - case 3: // CD + case rasctl_dev_cd: // CD pUnit = new SCSICD(); break; - case 4: // BRIDGE + case rasctl_dev_br: // BRIDGE pUnit = new SCSIBR(); break; + // case rasctl_dev_nuvolink: // Nuvolink + // pUnit = new SCSINuvolink(); + // break; + case rasctl_dev_daynaport: // DaynaPort SCSI Link + pUnit = new SCSIDaynaPort(); + break; default: FPRT(fp, "Error : Invalid device type\n"); return FALSE; diff --git a/src/raspberrypi/rasctl.cpp b/src/raspberrypi/rasctl.cpp index c99e5d01..406b814f 100644 --- a/src/raspberrypi/rasctl.cpp +++ b/src/raspberrypi/rasctl.cpp @@ -11,6 +11,7 @@ #include "os.h" #include "rascsi_version.h" +#include "rasctl.h" //--------------------------------------------------------------------------- // @@ -95,7 +96,7 @@ int main(int argc, char* argv[]) fprintf(stderr, " where ID := {0|1|2|3|4|5|6|7}\n"); fprintf(stderr, " UNIT := {0|1} default setting is 0.\n"); fprintf(stderr, " CMD := {attach|detach|insert|eject|protect}\n"); - fprintf(stderr, " TYPE := {hd|mo|cd|bridge}\n"); + fprintf(stderr, " TYPE := {hd|mo|cd|bridge|daynaport}\n"); fprintf(stderr, " FILE := image file path\n"); fprintf(stderr, " CMD is 'attach' or 'insert' and FILE parameter is required.\n"); fprintf(stderr, "Usage: %s -l\n", argv[0]); @@ -146,19 +147,29 @@ int main(int argc, char* argv[]) case 'S': case 'h': // HD(SCSI) case 'H': - type = 0; + // rascsi will figure out if this should be SASI or + // SCSI later in the process.... + type = rasctl_dev_sasi_hd; break; case 'm': // MO case 'M': - type = 2; + type = rasctl_dev_mo; break; case 'c': // CD case 'C': - type = 3; + type = rasctl_dev_cd; break; case 'b': // BRIDGE case 'B': - type = 4; + type = rasctl_dev_br; + break; + // case 'n': // Nuvolink + // case 'N': + // type = rasctl_dev_nuvolink; + // break; + case 'd': // DaynaPort + case 'D': + type = rasctl_dev_daynaport; break; } break; @@ -182,13 +193,13 @@ int main(int argc, char* argv[]) // Check the ID number if (id < 0 || id > 7) { - fprintf(stderr, "Error : Invalid ID\n"); + fprintf(stderr, "%s Error : Invalid ID %d \n", __PRETTY_FUNCTION__, id); exit(EINVAL); } // Check the unit number if (un < 0 || un > 1) { - fprintf(stderr, "Error : Invalid UNIT\n"); + fprintf(stderr, "%s Error : Invalid UNIT %d \n", __PRETTY_FUNCTION__, un); exit(EINVAL); } diff --git a/src/raspberrypi/rasctl.h b/src/raspberrypi/rasctl.h new file mode 100644 index 00000000..a56e95dd --- /dev/null +++ b/src/raspberrypi/rasctl.h @@ -0,0 +1,24 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI (*^..^*) +// for Raspberry Pi +// +// Powered by XM6 TypeG Technology. +// Copyright (C) 2016-2020 GIMONS +// Copyright (C) akuker +// +// [ Send Control Command ] +// +//--------------------------------------------------------------------------- + + +enum rasctl_dev_type : int { + rasctl_dev_invalid = -1, + rasctl_dev_sasi_hd = 0, + rasctl_dev_scsi_hd = 1, + rasctl_dev_mo = 2, + rasctl_dev_cd = 3, + rasctl_dev_br = 4, + rasctl_dev_nuvolink = 5, + rasctl_dev_daynaport = 6, +}; diff --git a/src/raspberrypi/rasdump.cpp b/src/raspberrypi/rasdump.cpp index 776103dc..4d6d60e0 100644 --- a/src/raspberrypi/rasdump.cpp +++ b/src/raspberrypi/rasdump.cpp @@ -5,7 +5,7 @@ // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS -// [ HDDダンプユーティリティ(イニシーエタモード) ] +// [ HDD dump utility (initiator mode) ] // //--------------------------------------------------------------------------- @@ -18,46 +18,46 @@ //--------------------------------------------------------------------------- // -// 定数宣言 +// Constant Declaration // //--------------------------------------------------------------------------- -#define BUFSIZE 1024 * 64 // 64KBぐらいかなぁ +#define BUFSIZE 1024 * 64 // Buffer size of about 64KB //--------------------------------------------------------------------------- // -// 変数宣言 +// Variable Declaration // //--------------------------------------------------------------------------- -GPIOBUS bus; // バス -int targetid; // ターゲットデバイスID -int boardid; // ボードID(自身のID) -Filepath hdsfile; // HDSファイル -BOOL restore; // リストアフラグ -BYTE buffer[BUFSIZE]; // ワークバッファ -int result; // 結果コード +GPIOBUS bus; // Bus +int targetid; // Target ID +int boardid; // Board ID (own ID) +Filepath hdsfile; // HDS file +BOOL restore; // Restore flag +BYTE buffer[BUFSIZE]; // Work Buffer +int result; // Result Code //--------------------------------------------------------------------------- // -// 関数宣言 +// Cleanup() Function declaration // //--------------------------------------------------------------------------- void Cleanup(); //--------------------------------------------------------------------------- // -// シグナル処理 +// Signal processing // //--------------------------------------------------------------------------- void KillHandler(int sig) { - // 停止指示 + // Stop running Cleanup(); exit(0); } //--------------------------------------------------------------------------- // -// バナー出力 +// Banner Output // //--------------------------------------------------------------------------- BOOL Banner(int argc, char* argv[]) @@ -82,12 +82,12 @@ BOOL Banner(int argc, char* argv[]) //--------------------------------------------------------------------------- // -// 初期化 +// Initialization // //--------------------------------------------------------------------------- BOOL Init() { - // 割り込みハンドラ設定 + // Interrupt handler setting if (signal(SIGINT, KillHandler) == SIG_ERR) { return FALSE; } @@ -98,12 +98,12 @@ BOOL Init() return FALSE; } - // GPIO初期化 + // GPIO Initialization if (!bus.Init(BUS::INITIATOR)) { return FALSE; } - // ワーク初期化 + // Work Intitialization targetid = -1; boardid = 7; restore = FALSE; @@ -113,29 +113,29 @@ BOOL Init() //--------------------------------------------------------------------------- // -// クリーンアップ +// Cleanup // //--------------------------------------------------------------------------- void Cleanup() { - // バスをクリーンアップ + // Cleanup the bus bus.Cleanup(); } //--------------------------------------------------------------------------- // -// リセット +// Reset // //--------------------------------------------------------------------------- void Reset() { - // バス信号線をリセット + // Reset the bus signal line bus.Reset(); } //--------------------------------------------------------------------------- // -// 引数処理 +// Argument processing // //--------------------------------------------------------------------------- BOOL ParseArgument(int argc, char* argv[]) @@ -143,10 +143,10 @@ BOOL ParseArgument(int argc, char* argv[]) int opt; char *file; - // 初期化 + // Initialization file = NULL; - // 引数解析 + // Argument Parsing opterr = 0; while ((opt = getopt(argc, argv, "i:b:f:r")) != -1) { switch (opt) { @@ -168,28 +168,28 @@ BOOL ParseArgument(int argc, char* argv[]) } } - // TARGET IDチェック + // TARGET ID check if (targetid < 0 || targetid > 7) { fprintf(stderr, "Error : Invalid target id range\n"); return FALSE; } - // BOARD IDチェック + // BOARD ID check if (boardid < 0 || boardid > 7) { fprintf(stderr, "Error : Invalid board id range\n"); return FALSE; } - // TARGETとBOARDのID重複チェック + // Target and Board ID duplication check if (targetid == boardid) { fprintf(stderr, "Error : Invalid target or board id\n"); return FALSE; } - // ファイルチェック + // File Check if (!file) { fprintf(stderr, "Error : Invalid file path\n"); @@ -203,14 +203,14 @@ BOOL ParseArgument(int argc, char* argv[]) //--------------------------------------------------------------------------- // -// フェーズ待ち +// Wait Phase // //--------------------------------------------------------------------------- BOOL WaitPhase(BUS::phase_t phase) { DWORD now; - // タイムアウト(3000ms) + // Timeout (3000ms) now = SysTimer::GetTimerLow(); while ((SysTimer::GetTimerLow() - now) < 3 * 1000 * 1000) { bus.Aquire(); @@ -224,18 +224,18 @@ BOOL WaitPhase(BUS::phase_t phase) //--------------------------------------------------------------------------- // -// バスフリーフェーズ実行 +// Bus Free Phase // //--------------------------------------------------------------------------- void BusFree() { - // バスリセット + // Bus Reset bus.Reset(); } //--------------------------------------------------------------------------- // -// セレクションフェーズ実行 +// Selection Phase // //--------------------------------------------------------------------------- BOOL Selection(int id) @@ -243,14 +243,14 @@ BOOL Selection(int id) BYTE data; int count; - // ID設定とSELアサート + // ID setting and SEL assert data = 0; data |= (1 << boardid); data |= (1 << id); bus.SetDAT(data); bus.SetSEL(TRUE); - // BSYを待つ + // wait for busy count = 10000; do { usleep(20); @@ -260,127 +260,128 @@ BOOL Selection(int id) } } while (count--); - // SELネゲート + // SEL negate bus.SetSEL(FALSE); - // ターゲットがビジー状態なら成功 + // Success if the target is busy return bus.GetBSY(); } //--------------------------------------------------------------------------- // -// コマンドフェーズ実行 +// Command Phase // //--------------------------------------------------------------------------- BOOL Command(BYTE *buf, int length) { int count; - // フェーズ待ち + // Waiting for Phase if (!WaitPhase(BUS::command)) { return FALSE; } - // コマンド送信 + // Send Command count = bus.SendHandShake(buf, length); - // 送信結果が依頼数と同じなら成功 + // Success if the transmission result is the same as the number + // of requests if (count == length) { return TRUE; } - // 送信エラー + // Return error return FALSE; } //--------------------------------------------------------------------------- // -// データインフェーズ実行 +// Data in phase // //--------------------------------------------------------------------------- int DataIn(BYTE *buf, int length) { - // フェーズ待ち + // Wait for phase if (!WaitPhase(BUS::datain)) { return -1; } - // データ受信 + // Data reception return bus.ReceiveHandShake(buf, length); } //--------------------------------------------------------------------------- // -// データアウトフェーズ実行 +// Data out phase // //--------------------------------------------------------------------------- int DataOut(BYTE *buf, int length) { - // フェーズ待ち + // Wait for phase if (!WaitPhase(BUS::dataout)) { return -1; } - // データ受信 + // Data transmission return bus.SendHandShake(buf, length); } //--------------------------------------------------------------------------- // -// ステータスフェーズ実行 +// Status Phase // //--------------------------------------------------------------------------- int Status() { BYTE buf[256]; - // フェーズ待ち + // Wait for phase if (!WaitPhase(BUS::status)) { return -2; } - // データ受信 + // Data reception if (bus.ReceiveHandShake(buf, 1) == 1) { return (int)buf[0]; } - // 受信エラー + // Return error return -1; } //--------------------------------------------------------------------------- // -// メッセージインフェーズ実行 +// Message in phase // //--------------------------------------------------------------------------- int MessageIn() { BYTE buf[256]; - // フェーズ待ち + // Wait for phase if (!WaitPhase(BUS::msgin)) { return -2; } - // データ受信 + // Data reception if (bus.ReceiveHandShake(buf, 1) == 1) { return (int)buf[0]; } - // 受信エラー + // Return error return -1; } //--------------------------------------------------------------------------- // -// TEST UNIT READY実行 +// TEST UNIT READY // //--------------------------------------------------------------------------- int TestUnitReady(int id) { BYTE cmd[256]; - // 結果コード初期化 + // Result code initialization result = 0; // SELECTION @@ -410,7 +411,7 @@ int TestUnitReady(int id) } exit: - // バスフリー + // Bus free BusFree(); return result; @@ -418,7 +419,7 @@ exit: //--------------------------------------------------------------------------- // -// REQUEST SENSE実行 +// REQUEST SENSE // //--------------------------------------------------------------------------- int RequestSense(int id, BYTE *buf) @@ -426,7 +427,7 @@ int RequestSense(int id, BYTE *buf) BYTE cmd[256]; int count; - // 結果コード初期化 + // Result code initialization result = 0; count = 0; @@ -466,10 +467,10 @@ int RequestSense(int id, BYTE *buf) } exit: - // バスフリー + // Bus Free BusFree(); - // 成功であれば転送数を返す + // Returns the number of transfers if successful if (result == 0) { return count; } @@ -479,7 +480,7 @@ exit: //--------------------------------------------------------------------------- // -// MODE SENSE実行 +// MODE SENSE // //--------------------------------------------------------------------------- int ModeSense(int id, BYTE *buf) @@ -487,7 +488,7 @@ int ModeSense(int id, BYTE *buf) BYTE cmd[256]; int count; - // 結果コード初期化 + // Result code initialization result = 0; count = 0; @@ -528,10 +529,10 @@ int ModeSense(int id, BYTE *buf) } exit: - // バスフリー + // Bus free BusFree(); - // 成功であれば転送数を返す + // Returns the number of transfers if successful if (result == 0) { return count; } @@ -541,7 +542,7 @@ exit: //--------------------------------------------------------------------------- // -// INQUIRY実行 +// INQUIRY // //--------------------------------------------------------------------------- int Inquiry(int id, BYTE *buf) @@ -549,7 +550,7 @@ int Inquiry(int id, BYTE *buf) BYTE cmd[256]; int count; - // 結果コード初期化 + // Result code initialization result = 0; count = 0; @@ -589,10 +590,10 @@ int Inquiry(int id, BYTE *buf) } exit: - // バスフリー + // Bus free BusFree(); - // 成功であれば転送数を返す + // Returns the number of transfers if successful if (result == 0) { return count; } @@ -602,7 +603,7 @@ exit: //--------------------------------------------------------------------------- // -// READ CAPACITY実行 +// READ CAPACITY // //--------------------------------------------------------------------------- int ReadCapacity(int id, BYTE *buf) @@ -610,7 +611,7 @@ int ReadCapacity(int id, BYTE *buf) BYTE cmd[256]; int count; - // 結果コード初期化 + // Result code initialization result = 0; count = 0; @@ -649,10 +650,10 @@ int ReadCapacity(int id, BYTE *buf) } exit: - // バスフリー + // Bus free BusFree(); - // 成功であれば転送数を返す + // Returns the number of transfers if successful if (result == 0) { return count; } @@ -662,7 +663,7 @@ exit: //--------------------------------------------------------------------------- // -// READ10実行 +// READ10 // //--------------------------------------------------------------------------- int Read10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) @@ -670,7 +671,7 @@ int Read10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) BYTE cmd[256]; int count; - // 結果コード初期化 + // Result code initialization result = 0; count = 0; @@ -714,10 +715,10 @@ int Read10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) } exit: - // バスフリー + // Bus free BusFree(); - // 成功であれば転送数を返す + // Returns the number of transfers if successful if (result == 0) { return count; } @@ -727,7 +728,7 @@ exit: //--------------------------------------------------------------------------- // -// WRITE10実行 +// WRITE10 // //--------------------------------------------------------------------------- int Write10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) @@ -735,7 +736,7 @@ int Write10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) BYTE cmd[256]; int count; - // 結果コード初期化 + // Result code initialization result = 0; count = 0; @@ -779,10 +780,10 @@ int Write10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) } exit: - // バスフリー + // Bus free BusFree(); - // 成功であれば転送数を返す + // Returns the number of transfers if successful if (result == 0) { return count; } @@ -792,7 +793,7 @@ exit: //--------------------------------------------------------------------------- // -// 主処理 +// Main process // //--------------------------------------------------------------------------- int main(int argc, char* argv[]) @@ -809,32 +810,32 @@ int main(int argc, char* argv[]) Fileio::OpenMode omode; off64_t size; - // バナー出力 + // Banner output if (!Banner(argc, argv)) { exit(0); } - // 初期化 + // Initialization if (!Init()) { - fprintf(stderr, "Error : Initializing\n"); + fprintf(stderr, "Error : Initializing. Are you root?\n"); - // 恐らくrootでは無い? + // Probably not root exit(EPERM); } - // 構築 + // Prase Argument if (!ParseArgument(argc, argv)) { - // クリーンアップ + // Cleanup Cleanup(); - // 引数エラーで終了 + // Exit with invalid argument error exit(EINVAL); } - // リセット + // Reset the SCSI bus Reset(); - // ファイルオープン + // File Open if (restore) { omode = Fileio::ReadOnly; } else { @@ -843,20 +844,20 @@ int main(int argc, char* argv[]) if (!fio.Open(hdsfile.GetPath(), omode)) { fprintf(stderr, "Error : Can't open hds file\n"); - // クリーンアップ + // Cleanup Cleanup(); exit(EPERM); } - // バスフリー + // Bus free BusFree(); - // RESETシグナル発行 + // Assert reset signal bus.SetRST(TRUE); usleep(1000); bus.SetRST(FALSE); - // ダンプ開始 + // Start dump printf("TARGET ID : %d\n", targetid); printf("BORAD ID : %d\n", boardid); @@ -881,7 +882,7 @@ int main(int argc, char* argv[]) goto cleanup_exit; } - // INQUIRYの情報を表示 + // Display INQUIRY information memset(str, 0x00, sizeof(str)); memcpy(str, &buffer[8], 8); printf("Vendor : %s\n", str); @@ -892,14 +893,14 @@ int main(int argc, char* argv[]) memcpy(str, &buffer[32], 4); printf("Revison : %s\n", str); - // 容量取得 + // Get drive capacity count = ReadCapacity(targetid, buffer); if (count < 0) { fprintf(stderr, "READ CAPACITY ERROR %d\n", count); goto cleanup_exit; } - // ブロックサイズとブロック数の表示 + // Display block size and number of blocks bsiz = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; @@ -913,7 +914,7 @@ int main(int argc, char* argv[]) (int)(bsiz * bnum / 1024 / 1024), (int)(bsiz * bnum)); - // リストアファイルサイズの取得 + // Get the restore file size if (restore) { size = fio.GetFileSize(); printf("Restore file size : %d bytes", (int)size); @@ -926,7 +927,7 @@ int main(int argc, char* argv[]) printf("\n"); } - // バッファサイズ毎にダンプする + // Dump by buffer size duni = BUFSIZE; duni /= bsiz; dsiz = BUFSIZE; @@ -974,7 +975,7 @@ int main(int argc, char* argv[]) printf("\033[0K"); } - // 容量上の端数処理 + // Rounding on capacity dnum = bnum % duni; dsiz = dnum * bsiz; if (dnum > 0) { @@ -989,16 +990,16 @@ int main(int argc, char* argv[]) } } - // 完了メッセージ + // Completion Message printf("%3d%%(%7d/%7d)\n", 100, (int)bnum, (int)bnum); cleanup_exit: - // ファイルクローズ + // File close fio.Close(); - // クリーンアップ + // Cleanup Cleanup(); - // 終了 + // end exit(0); } diff --git a/src/raspberrypi/scsi.h b/src/raspberrypi/scsi.h index a1ee4259..906d0fd0 100644 --- a/src/raspberrypi/scsi.h +++ b/src/raspberrypi/scsi.h @@ -28,13 +28,13 @@ public: }; // Phase definition - enum phase_t { + enum phase_t : BYTE { busfree, // バスフリーフェーズ arbitration, // アービトレーションフェーズ selection, // セレクションフェーズ reselection, // リセレクションフェーズ command, // コマンドフェーズ - execute, // 実行フェーズ + execute, // 実行フェーズ Execute is an extension of the command phase datain, // データイン dataout, // データアウト status, // ステータスフェーズ @@ -128,6 +128,14 @@ public: virtual int FASTCALL SendHandShake(BYTE *buf, int count) = 0; // データ送信ハンドシェイク + + virtual BOOL FASTCALL GetSignal(int pin) = 0; + // Get SCSI input signal value + virtual void FASTCALL SetSignal(int pin, BOOL ast) = 0; + // Set SCSI output signal value +protected: + phase_t m_current_phase = phase_t::reserved; + private: static const phase_t phase_table[8]; // フェーズテーブル @@ -135,4 +143,84 @@ private: static const char* phase_str_table[]; }; + +typedef struct __attribute__((packed)) { + BYTE operation_code; + BYTE misc_cdb_information; + BYTE page_code; + WORD length; + BYTE control; +} scsi_cdb_6_byte_t; + + +typedef struct __attribute__((packed)) { + BYTE operation_code; + BYTE service_action; + DWORD logical_block_address; + BYTE misc_cdb_information; + WORD length; + BYTE control; +} scsi_cdb_10_byte_t; + +typedef struct __attribute__((packed)) { + BYTE operation_code; + BYTE service_action; + DWORD logical_block_address; + DWORD length; + BYTE misc_cdb_information; + BYTE control; +} scsi_cdb_12_byte_t; + +typedef struct __attribute__((packed)) { + BYTE operation_code; + BYTE service_action; + DWORD logical_block_address; + DWORD length; + BYTE misc_cdb_information; + BYTE control; +} scsi_cdb_16_byte_t; + +typedef struct __attribute__((packed)) { + BYTE operation_code; + BYTE reserved; + BYTE page_code; + WORD allocation_length; + BYTE control; +} scsi_cmd_inquiry_t; + +typedef struct __attribute__((packed)) { + BYTE operation_code; + BYTE lba_msb_bits_4_0; + WORD logical_block_address; + BYTE transfer_length; + BYTE control; +} scsi_cmd_read_6_t; + +typedef struct __attribute__((packed)) { + BYTE operation_code; + BYTE flags; + DWORD logical_block_address; + BYTE group_number; + WORD transfer_length; + BYTE control; +} scsi_cmd_read_10_t; + +typedef struct __attribute__((packed)) { + BYTE operation_code; + BYTE flags; + DWORD logical_block_address; + DWORD transfer_length; + BYTE group_number; + BYTE control; +} scsi_cmd_read_12_t; + +typedef struct __attribute__((packed)) { + BYTE operation_code; + BYTE descriptor_format; + WORD reserved; + BYTE allocation_length; + BYTE control; +} scsi_cmd_request_sense_t; + + #endif // scsi_h diff --git a/src/raspberrypi/setup_bridge.sh b/src/raspberrypi/setup_bridge.sh new file mode 100755 index 00000000..d81e7358 --- /dev/null +++ b/src/raspberrypi/setup_bridge.sh @@ -0,0 +1,7 @@ +#!/bin/bash +sudo brctl addbr rascsi_bridge +sudo brctl addif rascsi_bridge eth0 +sudo ip link set dev rascsi_bridge up + +echo Bridge config: +brctl show From bc561d65dd80ab101361b79c625c00021fe65eed Mon Sep 17 00:00:00 2001 From: Tony Kuker Date: Sat, 30 Jan 2021 12:36:18 -0600 Subject: [PATCH 07/22] Changed system call to use fork/wait. Moved some disk functions out of the header --- .gitignore | 2 ++ src/raspberrypi/.vscode/launch.json | 4 ++- src/raspberrypi/.vscode/tasks.json | 2 +- src/raspberrypi/Makefile | 1 + src/raspberrypi/controllers/scsidev_ctrl.cpp | 2 +- src/raspberrypi/devices/ctapdriver.cpp | 31 ++++++++++------ src/raspberrypi/devices/disk.cpp | 32 +++++++++++++++++ src/raspberrypi/devices/disk.h | 6 ++-- src/raspberrypi/devices/scsi_daynaport.cpp | 9 ++--- src/raspberrypi/os.cpp | 35 +++++++++++++++++++ src/raspberrypi/os.h | 3 ++ src/raspberrypi/os_integration/rascsi.service | 2 +- src/raspberrypi/rascsi.cpp | 5 ++- 13 files changed, 109 insertions(+), 25 deletions(-) create mode 100644 src/raspberrypi/os.cpp diff --git a/.gitignore b/.gitignore index 5ceb3864..995e1e8a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ venv +*.pyc +core diff --git a/src/raspberrypi/.vscode/launch.json b/src/raspberrypi/.vscode/launch.json index 4ac5ab4b..b58c19b7 100644 --- a/src/raspberrypi/.vscode/launch.json +++ b/src/raspberrypi/.vscode/launch.json @@ -8,13 +8,15 @@ "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/bin/rascsi", + "program": "${workspaceFolder}/bin/fullspec/rascsi", "args": [], "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", + "targetArchitecture": "arm", + "miDebuggerPath": "${workspaceFolder}/launch_sudo.sh", "setupCommands": [ { "description": "Enable pretty-printing for gdb", diff --git a/src/raspberrypi/.vscode/tasks.json b/src/raspberrypi/.vscode/tasks.json index eeedfe8a..850ac6dd 100644 --- a/src/raspberrypi/.vscode/tasks.json +++ b/src/raspberrypi/.vscode/tasks.json @@ -5,7 +5,7 @@ "type": "shell", "label": "g++ build active file", "command": "make", - "args": ["all", "DEBUG=1"], + "args": ["all", "DEBUG=1", "-j4"], "options": { "cwd": "${workspaceFolder}/" }, diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index c2424c65..9a9984be 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -75,6 +75,7 @@ SRC_RASCSI = \ gpiobus.cpp \ filepath.cpp \ fileio.cpp\ + os.cpp\ rascsi_version.cpp # os.cpp # rasctl_command.cpp diff --git a/src/raspberrypi/controllers/scsidev_ctrl.cpp b/src/raspberrypi/controllers/scsidev_ctrl.cpp index ce5417a2..da9b6b79 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.cpp +++ b/src/raspberrypi/controllers/scsidev_ctrl.cpp @@ -559,7 +559,7 @@ void FASTCALL SCSIDEV::CmdInquiry() if (disk) { major = (DWORD)(RASCSI >> 8); minor = (DWORD)(RASCSI & 0xff); - LOGINFO("%s Buffer size is %d",__PRETTY_FUNCTION__, ctrl.bufsize); + LOGTRACE("%s Buffer size is %d",__PRETTY_FUNCTION__, ctrl.bufsize); ctrl.length = ctrl.unit[lun]->Inquiry(ctrl.cmd, ctrl.buffer, major, minor); } else { diff --git a/src/raspberrypi/devices/ctapdriver.cpp b/src/raspberrypi/devices/ctapdriver.cpp index fd5c941c..188fda41 100644 --- a/src/raspberrypi/devices/ctapdriver.cpp +++ b/src/raspberrypi/devices/ctapdriver.cpp @@ -48,35 +48,44 @@ BOOL FASTCALL CTapDriver::Init() ASSERT(this); + LOGTRACE("Opening Tap device"); // TAP device initilization if ((m_hTAP = open("/dev/net/tun", O_RDWR)) < 0) { LOGERROR("Error: can't open tun. Errno: %d %s", errno, strerror(errno)); return FALSE; } + LOGTRACE("Opened tap device %d",m_hTAP); + // IFF_NO_PI for no extra packet information memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy(ifr.ifr_name, dev, IFNAMSIZ); + LOGTRACE("Going to open %s", ifr.ifr_name); if ((ret = ioctl(m_hTAP, TUNSETIFF, (void *)&ifr)) < 0) { LOGERROR("Error: can't ioctl TUNSETIFF. Errno: %d %s", errno, strerror(errno)); close(m_hTAP); return FALSE; } + LOGTRACE("return code from ioctl was %d", ret); - // Force the tap interface up LOGDEBUG("ip link set ras0 up"); - system("ip link set ras0 up"); + ret = run_system_cmd("ip link set ras0 up"); + LOGTRACE("return code from ip link set ras0 up was %d", ret); + LOGDEBUG("brctl addif rascsi_bridge ras0"); - system("brctl addif rascsi_bridge ras0"); - + ret = run_system_cmd("brctl addif rascsi_bridge ras0"); + LOGTRACE("return code from brctl addif rascsi_bridge ras0 was %d", ret); + // Get MAC address + LOGTRACE("Getting the MAC address"); ifr.ifr_addr.sa_family = AF_INET; if ((ret = ioctl(m_hTAP, SIOCGIFHWADDR, &ifr)) < 0) { LOGERROR("Error: can't ioctl SIOCGIFHWADDR. Errno: %d %s", errno, strerror(errno)); close(m_hTAP); return FALSE; } + LOGTRACE("got the mac"); // Save MAC address memcpy(m_MacAddr, ifr.ifr_hwaddr.sa_data, sizeof(m_MacAddr)); @@ -141,20 +150,20 @@ BOOL FASTCALL CTapDriver::Init() void FASTCALL CTapDriver::Cleanup() { ASSERT(this); - + int result; LOGDEBUG("brctl delif rascsi_bridge ras0"); - system("brctl delif rascsi_bridge ras0"); + result = run_system_cmd("brctl delif rascsi_bridge ras0"); + if(result != EXIT_SUCCESS){ + LOGWARN("Warning: The brctl delif command failed."); + LOGWARN("You may need to manually remove the ras0 tap device from the bridge"); + } - - // Release TAP device + // Release TAP defice if (m_hTAP != -1) { close(m_hTAP); m_hTAP = -1; } - - - } //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/devices/disk.cpp b/src/raspberrypi/devices/disk.cpp index e97142ed..4701b2ff 100644 --- a/src/raspberrypi/devices/disk.cpp +++ b/src/raspberrypi/devices/disk.cpp @@ -974,6 +974,7 @@ BOOL FASTCALL Disk::IsNULL() const } return FALSE; } + //--------------------------------------------------------------------------- // // Retrieve the disk's ID @@ -984,6 +985,37 @@ DWORD FASTCALL Disk::GetID() const return disk.id; } + +//--------------------------------------------------------------------------- +// +// Get cache writeback mode +// +//--------------------------------------------------------------------------- +BOOL FASTCALL Disk::IsCacheWB() +{ + return cache_wb; +} + +//--------------------------------------------------------------------------- +// +// Set cache writeback mode +// +//--------------------------------------------------------------------------- +void FASTCALL Disk::SetCacheWB(BOOL enable) +{ + cache_wb = enable; +} + +//--------------------------------------------------------------------------- +// +// Set unsupported command +// +//--------------------------------------------------------------------------- +void FASTCALL Disk::InvalidCmd() +{ + disk.code = DISK_INVALIDCMD; +} + //--------------------------------------------------------------------------- // // SASI Check diff --git a/src/raspberrypi/devices/disk.h b/src/raspberrypi/devices/disk.h index ae9e5de9..5f8e9da3 100644 --- a/src/raspberrypi/devices/disk.h +++ b/src/raspberrypi/devices/disk.h @@ -328,13 +328,13 @@ public: // PLAY AUDIO MSF command virtual BOOL FASTCALL PlayAudioTrack(const DWORD *cdb); // PLAY AUDIO TRACK command - void FASTCALL InvalidCmd() { disk.code = DISK_INVALIDCMD; } + void FASTCALL InvalidCmd(); // Unsupported command // Other - BOOL IsCacheWB() { return cache_wb; } + BOOL FASTCALL IsCacheWB(); // Get cache writeback mode - void SetCacheWB(BOOL enable) { cache_wb = enable; } + void FASTCALL SetCacheWB(BOOL enable); // Set cache writeback mode protected: diff --git a/src/raspberrypi/devices/scsi_daynaport.cpp b/src/raspberrypi/devices/scsi_daynaport.cpp index ff8ec5f6..6eebad4c 100644 --- a/src/raspberrypi/devices/scsi_daynaport.cpp +++ b/src/raspberrypi/devices/scsi_daynaport.cpp @@ -38,10 +38,6 @@ const char* SCSIDaynaPort::m_firmware_version = "01.00.00"; const BYTE SCSIDaynaPort::m_bcast_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; const BYTE SCSIDaynaPort::m_apple_talk_addr[6] = { 0x09, 0x00, 0x07, 0xff, 0xff, 0xff }; -#ifndef NDEBUG -static DWORD file_counter = 0; -#endif - //--------------------------------------------------------------------------- // // Constructor @@ -63,11 +59,13 @@ SCSIDaynaPort::SCSIDaynaPort() : Disk() LOGINFO("Tap interface created") } + LOGTRACE("%s this->reset()", __PRETTY_FUNCTION__); this->Reset(); disk.ready = true; disk.reset = false; // Generate MAC Address + LOGTRACE("%s memset(m_mac_addr, 0x00, 6);", __PRETTY_FUNCTION__); memset(m_mac_addr, 0x00, 6); // if (m_bTapEnable) { @@ -76,6 +74,7 @@ SCSIDaynaPort::SCSIDaynaPort() : Disk() // } // !!!!!!!!!!!!!!!!! For now, hard code the MAC address. Its annoying when it keeps changing during development! // TODO: Remove this hard-coded address + LOGTRACE("%s m_mac_addr[0]=0x00;", __PRETTY_FUNCTION__); m_mac_addr[0]=0x00; m_mac_addr[1]=0x80; m_mac_addr[2]=0x19; @@ -299,8 +298,6 @@ int FASTCALL SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, DWORD block) buf[5] = 0; } - LOGTRACE("%s Packet of size %d received [Counter: %d]", __PRETTY_FUNCTION__, (int)rx_packet_size, (int)file_counter); - // Return the packet size + 2 for the length + 4 for the flag field // The CRC was already appended by the ctapdriver return rx_packet_size + m_read_header_size; diff --git a/src/raspberrypi/os.cpp b/src/raspberrypi/os.cpp new file mode 100644 index 00000000..50711802 --- /dev/null +++ b/src/raspberrypi/os.cpp @@ -0,0 +1,35 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI (*^..^*) +// for Raspberry Pi +// +// Powered by XM6 TypeG Technology. +// Copyright (C) 2016-2020 GIMONS +// Copyright (C) 2020-2021 akuker +// +// [ OS related definitions ] +// +//--------------------------------------------------------------------------- + +#include "os.h" +#include + + +//--------------------------------------------------------------------------- +// +// Run system command and wait for it to finish +// +//--------------------------------------------------------------------------- +int run_system_cmd(const char* command) +{ + pid_t pid; + int result; + int status = 0; + pid=fork(); + if(pid == 0){ + result = system(command); + exit(result); + } + waitpid(pid, &status, 0); + return status; +} \ No newline at end of file diff --git a/src/raspberrypi/os.h b/src/raspberrypi/os.h index cb145f7e..9cb9f31e 100644 --- a/src/raspberrypi/os.h +++ b/src/raspberrypi/os.h @@ -155,4 +155,7 @@ typedef const char *LPCSTR; #define xstrcasecmp strcasecmp #define xstrncasecmp strncasecmp +// Run system command and wait for it to finish +extern int run_system_cmd(const char* command); + #endif // os_h diff --git a/src/raspberrypi/os_integration/rascsi.service b/src/raspberrypi/os_integration/rascsi.service index d5072387..62fe6528 100644 --- a/src/raspberrypi/os_integration/rascsi.service +++ b/src/raspberrypi/os_integration/rascsi.service @@ -9,7 +9,7 @@ ExecStart=/usr/local/bin/rascsi # Example: If you want to automatically attach a hard disk at startup, change # the ExecStart line to: # ExecStart=/usr/local/bin/rascsi -ID1 /home/pi/images/harddisk.hda -ExecStop=/usr/local/bin/rasctl -stop +# This functionality isn't implmented yet: ExecStop=/usr/local/bin/rasctl -stop StandardOutput=syslog StandardError=syslog SyslogIdentifier=RASCSI diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index 331359a3..b08924a6 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -297,6 +297,8 @@ void ListDevice(FILE *fp) // mount status output if (pUnit->GetID() == MAKEID('S', 'C', 'B', 'R')) { FPRT(fp, "%s", "HOST BRIDGE"); + } else if (pUnit->GetID() == MAKEID('S', 'C', 'D', 'P')) { + FPRT(fp, "%s", "DaynaPort SCSI/Link"); } else { pUnit->GetPath(filepath); FPRT(fp, "%s", @@ -526,6 +528,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) // break; case rasctl_dev_daynaport: // DaynaPort SCSI Link pUnit = new SCSIDaynaPort(); + LOGTRACE("Done creating SCSIDayanPort"); break; default: FPRT(fp, "Error : Invalid device type\n"); @@ -533,7 +536,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) } // drive checks files - if (type <= 1 || (type <= 3 && xstrcasecmp(file, "-") != 0)) { + if (type <= rasctl_dev_scsi_hd || (type <= rasctl_dev_cd && xstrcasecmp(file, "-") != 0)) { // Set the Path filepath.SetPath(file); From 04a2f46f51eabdbd32d960d510ec676e0b5d0bfc Mon Sep 17 00:00:00 2001 From: Tony Kuker Date: Sat, 30 Jan 2021 14:07:05 -0600 Subject: [PATCH 08/22] added additional event loggin --- src/raspberrypi/rascsi.cpp | 50 ++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index b08924a6..9e972a1b 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -264,10 +264,12 @@ void ListDevice(FILE *fp) Filepath filepath; BOOL find; char type[5]; + char dev_status[_MAX_FNAME+26]; find = FALSE; type[4] = 0; for (i = 0; i < CtrlMax * UnitNum; i++) { + strncpy(dev_status,"",sizeof(dev_status)); // Initialize ID and unit number id = i / UnitNum; un = i % UnitNum; @@ -282,7 +284,9 @@ void ListDevice(FILE *fp) if (!find) { FPRT(fp, "\n"); FPRT(fp, "+----+----+------+-------------------------------------\n"); + LOGINFO( "+----+----+------+-------------------------------------"); FPRT(fp, "| ID | UN | TYPE | DEVICE STATUS\n"); + LOGINFO( "| ID | UN | TYPE | DEVICE STATUS\n"); FPRT(fp, "+----+----+------+-------------------------------------\n"); find = TRUE; } @@ -292,27 +296,26 @@ void ListDevice(FILE *fp) 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"); + strncpy(dev_status,"X68000 HOST BRIDGE",sizeof(dev_status)); } else if (pUnit->GetID() == MAKEID('S', 'C', 'D', 'P')) { - FPRT(fp, "%s", "DaynaPort SCSI/Link"); + strncpy(dev_status,"DaynaPort SCSI/Link",sizeof(dev_status)); } else { pUnit->GetPath(filepath); - FPRT(fp, "%s", + snprintf(dev_status, sizeof(dev_status), "%s", (pUnit->IsRemovable() && !pUnit->IsReady()) ? "NO MEDIA" : filepath.GetPath()); } // Write protection status if (pUnit->IsRemovable() && pUnit->IsReady() && pUnit->IsWriteP()) { - FPRT(fp, "(WRITEPROTECT)"); + strcat(dev_status, "(WRITEPROTECT)"); } + FPRT(fp, "| %d | %d | %s | %s\n", id, un, type, dev_status); + LOGINFO( "| %d | %d | %s | %s", id, un, type, dev_status); - // Goto the next line - FPRT(fp, "\n"); } // If there is no controller, find will be null @@ -322,6 +325,7 @@ void ListDevice(FILE *fp) } FPRT(fp, "+----+----+------+-------------------------------------\n"); + LOGINFO( "+----+----+------+-------------------------------------"); } //--------------------------------------------------------------------------- @@ -451,6 +455,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) char *ext; Filepath filepath; Disk *pUnit; + char type_str[5]; // Copy the Unit List memcpy(map, disk, sizeof(disk)); @@ -532,6 +537,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) break; default: FPRT(fp, "Error : Invalid device type\n"); + LOGWARN("rasctl sent a command for an invalid drive type: %d", type); return FALSE; } @@ -543,6 +549,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) // Open the file path if (!pUnit->Open(filepath)) { FPRT(fp, "Error : File open error [%s]\n", file); + LOGWARN("rasctl tried to open an invalid file %s", file); delete pUnit; return FALSE; } @@ -556,18 +563,26 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) // Re-map the controller MapControler(fp, map); + 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); return TRUE; } // Is this a valid command? if (cmd > 4) { FPRT(fp, "Error : Invalid command\n"); + LOGINFO("rasctl sent an invalid command: %d",cmd); return FALSE; } // Does the controller exist? if (ctrl[id] == NULL) { FPRT(fp, "Error : No such device\n"); + LOGWARN("rasctl sent a command for invalid controller %d", id); return FALSE; } @@ -575,11 +590,24 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) pUnit = disk[id * UnitNum + un]; if (pUnit == NULL) { FPRT(fp, "Error : No such device\n"); + LOGWARN("rasctl sent a command for invalid unit ID %d UN %d", id, un); return FALSE; } + type_str[0] = (char)(map[id * UnitNum + un]->GetID() >> 24); + type_str[1] = (char)(map[id * UnitNum + un]->GetID() >> 16); + type_str[2] = (char)(map[id * UnitNum + un]->GetID() >> 8); + type_str[3] = (char)(map[id * UnitNum + un]->GetID()); + type_str[4] = '\0'; + // Disconnect Command if (cmd == 1) { // DETACH + type_str[0] = (char)(map[id * UnitNum + un]->GetID() >> 24); + type_str[1] = (char)(map[id * UnitNum + un]->GetID() >> 16); + type_str[2] = (char)(map[id * UnitNum + un]->GetID() >> 8); + type_str[3] = (char)(map[id * UnitNum + un]->GetID()); + type_str[4] = '\0'; + LOGINFO("rasctl command disconnect %s at ID: %d UN: %d", type_str, id, un); // Free the existing unit map[id * UnitNum + un] = NULL; @@ -591,7 +619,8 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) // Valid only for MO or CD if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O') && pUnit->GetID() != MAKEID('S', 'C', 'C', 'D')) { - FPRT(fp, "Error : Operation denied(Deveice isn't removable)\n"); + FPRT(fp, "Error : Operation denied (Device type %s isn't removable)\n", type_str); + LOGWARN("rasctl sent an Insert/Eject/Protect command (%d) for incompatible type %s", cmd, type_str); return FALSE; } @@ -599,6 +628,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) case 2: // INSERT // Set the file path filepath.SetPath(file); + LOGINFO("rasctl commanded insert file %s into %s ID: %d UN: %d", file, type_str, id, un); // Open the file if (!pUnit->Open(filepath)) { @@ -608,17 +638,21 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) break; case 3: // EJECT + LOGINFO("rasctl commands eject %s ID: %d UN: %d", type_str, id, un); pUnit->Eject(TRUE); break; case 4: // PROTECT if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O')) { FPRT(fp, "Error : Operation denied(Deveice isn't MO)\n"); + LOGWARN("rasctl sent an invalid PROTECT command for %s ID: %d UN: %d", type_str, id, un); return FALSE; } + LOGINFO("rasctl is setting write protect to %d for %s ID: %d UN: %d",!pUnit->IsWriteP(), type_str, id, un); pUnit->WriteP(!pUnit->IsWriteP()); break; default: + LOGWARN("Received unknown command from rasctl: %d", cmd); ASSERT(FALSE); return FALSE; } From f1f60f281fcc7a700771cc55a7c3b74710f33c56 Mon Sep 17 00:00:00 2001 From: Tony Kuker Date: Sat, 30 Jan 2021 14:07:40 -0600 Subject: [PATCH 09/22] Updated ctapdriver to use the forked system call --- src/raspberrypi/devices/ctapdriver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raspberrypi/devices/ctapdriver.cpp b/src/raspberrypi/devices/ctapdriver.cpp index 188fda41..098c20df 100644 --- a/src/raspberrypi/devices/ctapdriver.cpp +++ b/src/raspberrypi/devices/ctapdriver.cpp @@ -174,7 +174,7 @@ void FASTCALL CTapDriver::Cleanup() BOOL FASTCALL CTapDriver::Enable(){ int result; LOGDEBUG("%s: ip link set ras0 up", __PRETTY_FUNCTION__); - result = system("ip link set ras0 up"); + result = run_system_cmd("ip link set ras0 up"); return (result == EXIT_SUCCESS); } @@ -186,7 +186,7 @@ BOOL FASTCALL CTapDriver::Enable(){ BOOL FASTCALL CTapDriver::Disable(){ int result; LOGDEBUG("%s: ip link set ras0 down", __PRETTY_FUNCTION__); - result = system("ip link set ras0 down"); + result = run_system_cmd("ip link set ras0 down"); return (result == EXIT_SUCCESS); } From 144abd45246984e988df2e60c241442d4eae8ef9 Mon Sep 17 00:00:00 2001 From: Tony Kuker Date: Sat, 30 Jan 2021 14:08:09 -0600 Subject: [PATCH 10/22] Cleanup extraneous debug printouts --- src/raspberrypi/devices/scsi_daynaport.cpp | 9 ++------- src/raspberrypi/devices/scsihd.cpp | 2 +- src/raspberrypi/log.h | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/raspberrypi/devices/scsi_daynaport.cpp b/src/raspberrypi/devices/scsi_daynaport.cpp index 6eebad4c..76bbfbbf 100644 --- a/src/raspberrypi/devices/scsi_daynaport.cpp +++ b/src/raspberrypi/devices/scsi_daynaport.cpp @@ -387,7 +387,7 @@ BOOL FASTCALL SCSIDaynaPort::Write(const DWORD *cdb, const BYTE *buf, DWORD bloc //--------------------------------------------------------------------------- int FASTCALL SCSIDaynaPort::RetrieveStats(const DWORD *cdb, BYTE *buffer) { - DWORD response_size; + DWORD response_size; DWORD allocation_length; // DWORD frame_alignment_errors; @@ -429,7 +429,7 @@ int FASTCALL SCSIDaynaPort::RetrieveStats(const DWORD *cdb, BYTE *buffer) for(int i=0; i< 6; i++) { - LOGINFO("%s CDB byte %d: %02X",__PRETTY_FUNCTION__, i, (unsigned int)cdb[i]); + LOGTRACE("%s CDB byte %d: %02X",__PRETTY_FUNCTION__, i, (unsigned int)cdb[i]); } response_size = 18; @@ -440,11 +440,6 @@ int FASTCALL SCSIDaynaPort::RetrieveStats(const DWORD *cdb, BYTE *buffer) LOGTRACE("%s response size is %d", __PRETTY_FUNCTION__, (int)response_size); - // // SendMessage6 is 18 bytes - // for(int i=0; i< 18; i++) - // { - // LOGDEBUG("%s Byte %d: %02X",__PRETTY_FUNCTION__, i, (int)buffer[i]); - // } if(response_size > allocation_length) { response_size = allocation_length; diff --git a/src/raspberrypi/devices/scsihd.cpp b/src/raspberrypi/devices/scsihd.cpp index cc9fa858..f7e7545b 100644 --- a/src/raspberrypi/devices/scsihd.cpp +++ b/src/raspberrypi/devices/scsihd.cpp @@ -241,7 +241,7 @@ BOOL FASTCALL SCSIHD::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) case 0x08: // Debug code for Issue #2: // https://github.com/akuker/RASCSI/issues/2 - printf("[Unhandled page code] Received mode page code 8 with total length %d\n ", length); + LOGWARN("[Unhandled page code] Received mode page code 8 with total length %d\n ", length); for (int i = 0; i Date: Sat, 30 Jan 2021 14:12:29 -0600 Subject: [PATCH 11/22] Cleanup extraneous debug printouts --- src/raspberrypi/devices/scsi_daynaport.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/raspberrypi/devices/scsi_daynaport.cpp b/src/raspberrypi/devices/scsi_daynaport.cpp index 76bbfbbf..f8f44ba7 100644 --- a/src/raspberrypi/devices/scsi_daynaport.cpp +++ b/src/raspberrypi/devices/scsi_daynaport.cpp @@ -17,6 +17,10 @@ // - SLINKCMD: http://www.bitsavers.org/pdf/apple/scsi/dayna/daynaPORT/SLINKCMD.TXT // - Tiny SCSI : https://hackaday.io/project/18974-tiny-scsi-emulator // +// Additional documentation and clarification is available at the +// following link: +// - https://github.com/akuker/RASCSI/wiki/Dayna-Port-SCSI-Link +// // This does NOT include the file system functionality that is present // in the Sharp X68000 host bridge. // @@ -56,7 +60,7 @@ SCSIDaynaPort::SCSIDaynaPort() : Disk() if(!m_bTapEnable){ LOGERROR("Unable to open the TAP interface"); }else { - LOGINFO("Tap interface created") + LOGDEBUG("Tap interface created") } LOGTRACE("%s this->reset()", __PRETTY_FUNCTION__); From 50bb0664dd23746d3bd88df8f6df6ed66d8228c2 Mon Sep 17 00:00:00 2001 From: akuker <34318535+akuker@users.noreply.github.com> Date: Sat, 30 Jan 2021 16:02:21 -0600 Subject: [PATCH 12/22] Update scsi_daynaport.cpp Missing semicolon when building non-debug build. --- src/raspberrypi/devices/scsi_daynaport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raspberrypi/devices/scsi_daynaport.cpp b/src/raspberrypi/devices/scsi_daynaport.cpp index f8f44ba7..4d6ce26d 100644 --- a/src/raspberrypi/devices/scsi_daynaport.cpp +++ b/src/raspberrypi/devices/scsi_daynaport.cpp @@ -60,7 +60,7 @@ SCSIDaynaPort::SCSIDaynaPort() : Disk() if(!m_bTapEnable){ LOGERROR("Unable to open the TAP interface"); }else { - LOGDEBUG("Tap interface created") + LOGDEBUG("Tap interface created"); } LOGTRACE("%s this->reset()", __PRETTY_FUNCTION__); From 3bf6c3ecd08c8cb93413430a34c197ff3b35d322 Mon Sep 17 00:00:00 2001 From: Tony Kuker Date: Sun, 31 Jan 2021 20:11:33 -0600 Subject: [PATCH 13/22] Updated to use a multi-thread safe logger --- src/raspberrypi/rascsi.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index 9e972a1b..3d30448e 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -28,6 +28,8 @@ #include "rascsi_version.h" #include "rasctl.h" #include "spdlog/spdlog.h" +#include "spdlog/sinks/stdout_color_sinks.h" +#include //--------------------------------------------------------------------------- // @@ -1109,6 +1111,9 @@ int main(int argc, char* argv[]) #endif // BAREMETAL spdlog::set_level(spdlog::level::trace); + // Create a thread-safe stdout logger to process the log messages + auto logger = spdlog::stdout_color_mt("rascsi stdout logger"); + LOGTRACE("Entering the function %s with %d arguments", __PRETTY_FUNCTION__, argc); // Output the Banner Banner(argc, argv); From 943a9ab5374f6db785d4fab4e2f982387547e6a7 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Mon, 1 Feb 2021 11:39:50 -0600 Subject: [PATCH 14/22] Black code formatting --- src/web/create_disk.py | 28 +++--- src/web/file_cmds.py | 30 ++++-- src/web/pi_cmds.py | 17 +++- src/web/ractl_cmds.py | 68 +++++++++---- src/web/settings.py | 4 +- src/web/web.py | 212 +++++++++++++++++++++++------------------ 6 files changed, 215 insertions(+), 144 deletions(-) diff --git a/src/web/create_disk.py b/src/web/create_disk.py index 2958c69d..6bc521ff 100644 --- a/src/web/create_disk.py +++ b/src/web/create_disk.py @@ -7,39 +7,39 @@ from settings import * def make_cd(file_path, file_type, file_creator): with open(file_path, "rb") as f: file_bytes = f.read() - file_name = file_path.split('/')[-1] - file_suffix = file_name.split('.')[-1] + file_name = file_path.split("/")[-1] + file_suffix = file_name.split(".")[-1] if file_type is None and file_creator is None: - if file_suffix.lower() == 'sea': - file_type = '.sea' - file_creator = 'APPL' + if file_suffix.lower() == "sea": + file_type = ".sea" + file_creator = "APPL" v = Volume() v.name = "TestName" - v['Folder'] = Folder() + v["Folder"] = Folder() - v['Folder'][file_name] = File() - v['Folder'][file_name].data = file_bytes - v['Folder'][file_name].rsrc = b'' + v["Folder"][file_name] = File() + v["Folder"][file_name].data = file_bytes + v["Folder"][file_name].rsrc = b"" if not (file_type is None and file_creator is None): - v['Folder'][file_name].type = bytearray(file_type) - v['Folder'][file_name].creator = bytearray(file_creator) + v["Folder"][file_name].type = bytearray(file_type) + v["Folder"][file_name].creator = bytearray(file_creator) padding = (len(file_bytes) % 512) + (512 * 50) print("mod", str(len(file_bytes) % 512)) print("padding " + str(padding)) print("len " + str(len(file_bytes))) print("total " + str(len(file_bytes) + padding)) - with open(base_dir + 'test.hda', 'wb') as f: + with open(base_dir + "test.hda", "wb") as f: flat = v.write( size=len(file_bytes) + padding, align=512, # Allocation block alignment modulus (2048 for CDs) desktopdb=True, # Create a dummy Desktop Database to prevent a rebuild on boot bootable=False, # This requires a folder with a ZSYS and a FNDR file - startapp=('Folder', file_name), # Path (as tuple) to an app to open at boot + startapp=("Folder", file_name), # Path (as tuple) to an app to open at boot ) f.write(flat) - return base_dir + 'test.hda' + return base_dir + "test.hda" diff --git a/src/web/file_cmds.py b/src/web/file_cmds.py index 415735a1..58512ed0 100644 --- a/src/web/file_cmds.py +++ b/src/web/file_cmds.py @@ -5,8 +5,9 @@ import time from ractl_cmds import attach_image from settings import * -valid_file_types = ['*.hda', '*.iso', '*.cdr'] -valid_file_types = r'|'.join([fnmatch.translate(x) for x in valid_file_types]) + +valid_file_types = ["*.hda", "*.iso", "*.cdr"] +valid_file_types = r"|".join([fnmatch.translate(x) for x in valid_file_types]) def create_new_image(file_name, type, size): @@ -15,8 +16,10 @@ def create_new_image(file_name, type, size): else: file_name = file_name + "." + type - return subprocess.run(["dd", "if=/dev/zero", "of=" + base_dir + file_name, "bs=1M", "count=" + size], - capture_output=True) + return subprocess.run( + ["dd", "if=/dev/zero", "of=" + base_dir + file_name, "bs=1M", "count=" + size], + capture_output=True, + ) def delete_image(file_name): @@ -30,18 +33,24 @@ def delete_image(file_name): def unzip_file(file_name): import zipfile - with zipfile.ZipFile(base_dir + file_name, 'r') as zip_ref: + + with zipfile.ZipFile(base_dir + file_name, "r") as zip_ref: zip_ref.extractall(base_dir) return True + def rascsi_service(action): # start/stop/restart - return subprocess.run(["sudo", "/bin/systemctl", action, "rascsi.service"]).returncode == 0 + return ( + subprocess.run(["sudo", "/bin/systemctl", action, "rascsi.service"]).returncode + == 0 + ) def download_file_to_iso(scsi_id, url): import urllib.request - file_name = url.split('/')[-1] + + file_name = url.split("/")[-1] tmp_ts = int(time.time()) tmp_dir = "/tmp/" + str(tmp_ts) + "/" os.mkdir(tmp_dir) @@ -50,7 +59,9 @@ def download_file_to_iso(scsi_id, url): urllib.request.urlretrieve(url, tmp_full_path) # iso_filename = make_cd(tmp_full_path, None, None) # not working yet - iso_proc = subprocess.run(["genisoimage", "-hfs", "-o", iso_filename, tmp_full_path], capture_output=True) + iso_proc = subprocess.run( + ["genisoimage", "-hfs", "-o", iso_filename, tmp_full_path], capture_output=True + ) if iso_proc.returncode != 0: return iso_proc return attach_image(scsi_id, iso_filename, "cd") @@ -58,7 +69,8 @@ def download_file_to_iso(scsi_id, url): def download_image(url): import urllib.request - file_name = url.split('/')[-1] + + file_name = url.split("/")[-1] full_path = base_dir + file_name urllib.request.urlretrieve(url, full_path) diff --git a/src/web/pi_cmds.py b/src/web/pi_cmds.py index 26f13086..17f716cc 100644 --- a/src/web/pi_cmds.py +++ b/src/web/pi_cmds.py @@ -3,7 +3,10 @@ import subprocess def rascsi_service(action): # start/stop/restart - return subprocess.run(["sudo", "/bin/systemctl", action, "rascsi.service"]).returncode == 0 + return ( + subprocess.run(["sudo", "/bin/systemctl", action, "rascsi.service"]).returncode + == 0 + ) def reboot_pi(): @@ -15,6 +18,14 @@ def shutdown_pi(): def running_version(): - ra_web_version = subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True).stdout.decode("utf-8").strip() - pi_version = subprocess.run(["uname", "-a"], capture_output=True).stdout.decode("utf-8").strip() + ra_web_version = ( + subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True) + .stdout.decode("utf-8") + .strip() + ) + pi_version = ( + subprocess.run(["uname", "-a"], capture_output=True) + .stdout.decode("utf-8") + .strip() + ) return ra_web_version + " " + pi_version diff --git a/src/web/ractl_cmds.py b/src/web/ractl_cmds.py index 38614983..60205903 100644 --- a/src/web/ractl_cmds.py +++ b/src/web/ractl_cmds.py @@ -4,8 +4,9 @@ import subprocess import re from settings import * -valid_file_types = ['*.hda', '*.iso', '*.cdr', '*.zip'] -valid_file_types = r'|'.join([fnmatch.translate(x) for x in valid_file_types]) + +valid_file_types = ["*.hda", "*.iso", "*.cdr", "*.zip"] +valid_file_types = r"|".join([fnmatch.translate(x) for x in valid_file_types]) # List of SCSI ID's you'd like to exclude - eg if you are on a Mac, the System is usually 7 EXCLUDE_SCSI_IDS = [7] @@ -20,19 +21,27 @@ def list_files(): for path, dirs, files in os.walk(base_dir): # Only list valid file types files = [f for f in files if re.match(valid_file_types, f)] - files_list.extend([ - (os.path.join(path, file), - # TODO: move formatting to template - '{:,.0f}'.format(os.path.getsize(os.path.join(path, file)) / float(1 << 20)) + " MB") - for file in files]) + files_list.extend( + [ + ( + os.path.join(path, file), + # TODO: move formatting to template + "{:,.0f}".format( + os.path.getsize(os.path.join(path, file)) / float(1 << 20) + ) + + " MB", + ) + for file in files + ] + ) return files_list def get_valid_scsi_ids(devices): invalid_list = EXCLUDE_SCSI_IDS.copy() for device in devices: - if device['file'] != "NO MEDIA" and device['file'] != "-": - invalid_list.append(int(device['id'])) + if device["file"] != "NO MEDIA" and device["file"] != "-": + invalid_list.append(int(device["id"])) valid_list = list(range(8)) for id in invalid_list: @@ -50,7 +59,10 @@ def attach_image(scsi_id, image, type): if type == "cd" and get_type(scsi_id) == "SCCD": return insert(scsi_id, image) else: - return subprocess.run(["rasctl", "-c", "attach", "-t", type, "-i", scsi_id, "-f", image], capture_output=True) + return subprocess.run( + ["rasctl", "-c", "attach", "-t", type, "-i", scsi_id, "-f", image], + capture_output=True, + ) def detach_by_id(scsi_id): @@ -58,7 +70,9 @@ def detach_by_id(scsi_id): def disconnect_by_id(scsi_id): - return subprocess.run(["rasctl", "-c", "disconnect", "-i", scsi_id], capture_output=True) + return subprocess.run( + ["rasctl", "-c", "disconnect", "-i", scsi_id], capture_output=True + ) def eject_by_id(scsi_id): @@ -66,33 +80,45 @@ def eject_by_id(scsi_id): def insert(scsi_id, image): - return subprocess.run(["rasctl", "-i", scsi_id, "-c", "insert", "-f", image], capture_output=True) + return subprocess.run( + ["rasctl", "-i", scsi_id, "-c", "insert", "-f", image], capture_output=True + ) def rascsi_service(action): # start/stop/restart - return subprocess.run(["sudo", "/bin/systemctl", action, "rascsi.service"]).returncode == 0 + return ( + subprocess.run(["sudo", "/bin/systemctl", action, "rascsi.service"]).returncode + == 0 + ) def list_devices(): device_list = [] for id in range(8): device_list.append({"id": str(id), "un": "-", "type": "-", "file": "-"}) - output = subprocess.run(["rasctl", "-l"], capture_output=True).stdout.decode("utf-8") + output = subprocess.run(["rasctl", "-l"], capture_output=True).stdout.decode( + "utf-8" + ) for line in output.splitlines(): # Valid line to process, continue - if not line.startswith("+") and \ - not line.startswith("| ID |") and \ - (not line.startswith("No device is installed.") or line.startswith("No images currently attached.")) \ - and len(line) > 0: + if ( + not line.startswith("+") + and not line.startswith("| ID |") + and ( + not line.startswith("No device is installed.") + or line.startswith("No images currently attached.") + ) + and len(line) > 0 + ): line.rstrip() device = {} segments = line.split("|") if len(segments) > 4: idx = int(segments[1].strip()) device_list[idx]["id"] = str(idx) - device_list[idx]['un'] = segments[2].strip() - device_list[idx]['type'] = segments[3].strip() - device_list[idx]['file'] = segments[4].strip() + device_list[idx]["un"] = segments[2].strip() + device_list[idx]["type"] = segments[3].strip() + device_list[idx]["file"] = segments[4].strip() return device_list diff --git a/src/web/settings.py b/src/web/settings.py index 24acee41..85036168 100644 --- a/src/web/settings.py +++ b/src/web/settings.py @@ -1,4 +1,4 @@ import os -base_dir = os.getenv('BASE_DIR', "/home/pi/images/") -MAX_FILE_SIZE = os.getenv('MAX_FILE_SIZE', 1024 * 1024 * 1024 * 2) # 2gb +base_dir = os.getenv("BASE_DIR", "/home/pi/images/") +MAX_FILE_SIZE = os.getenv("MAX_FILE_SIZE", 1024 * 1024 * 1024 * 2) # 2gb diff --git a/src/web/web.py b/src/web/web.py index f2965a7a..0fe3a20f 100644 --- a/src/web/web.py +++ b/src/web/web.py @@ -3,204 +3,226 @@ import os from flask import Flask, render_template, request, flash, url_for, redirect, send_file from werkzeug.utils import secure_filename -from file_cmds import create_new_image, download_file_to_iso, delete_image, unzip_file, download_image +from file_cmds import ( + create_new_image, + download_file_to_iso, + delete_image, + unzip_file, + download_image, +) from pi_cmds import shutdown_pi, reboot_pi, running_version, rascsi_service -from ractl_cmds import attach_image, list_devices, is_active, list_files, detach_by_id, eject_by_id, get_valid_scsi_ids +from ractl_cmds import ( + attach_image, + list_devices, + is_active, + list_files, + detach_by_id, + eject_by_id, + get_valid_scsi_ids, +) from settings import * app = Flask(__name__) -@app.route('/') + +@app.route("/") def index(): devices = list_devices() scsi_ids = get_valid_scsi_ids(devices) - return render_template('index.html', - devices=devices, - active=is_active(), - files=list_files(), - base_dir=base_dir, - scsi_ids=scsi_ids, - max_file_size=MAX_FILE_SIZE, - version=running_version()) + return render_template( + "index.html", + devices=devices, + active=is_active(), + files=list_files(), + base_dir=base_dir, + scsi_ids=scsi_ids, + max_file_size=MAX_FILE_SIZE, + version=running_version(), + ) -@app.route('/logs') + +@app.route("/logs") def logs(): import subprocess - lines = request.args.get('lines') or "100" + + lines = request.args.get("lines") or "100" process = subprocess.run(["journalctl", "-n", lines], capture_output=True) if process.returncode == 0: - headers = { 'content-type':'text/plain' } + headers = {"content-type": "text/plain"} return process.stdout.decode("utf-8"), 200, headers else: - flash(u'Failed to get logs') - flash(process.stdout.decode("utf-8"), 'stdout') - flash(process.stderr.decode("utf-8"), 'stderr') - return redirect(url_for('index')) + flash(u"Failed to get logs") + flash(process.stdout.decode("utf-8"), "stdout") + flash(process.stderr.decode("utf-8"), "stderr") + return redirect(url_for("index")) -@app.route('/scsi/attach', methods=['POST']) +@app.route("/scsi/attach", methods=["POST"]) def attach(): - file_name = request.form.get('file_name') - scsi_id = request.form.get('scsi_id') + file_name = request.form.get("file_name") + scsi_id = request.form.get("scsi_id") # Validate image type by suffix - if file_name.lower().endswith('.iso') or file_name.lower().endswith('iso'): + if file_name.lower().endswith(".iso") or file_name.lower().endswith("iso"): image_type = "cd" - elif file_name.lower().endswith('.hda'): + elif file_name.lower().endswith(".hda"): image_type = "hd" else: - flash(u'Unknown file type. Valid files are .iso, .hda, .cdr', 'error') - return redirect(url_for('index')) + flash(u"Unknown file type. Valid files are .iso, .hda, .cdr", "error") + return redirect(url_for("index")) process = attach_image(scsi_id, file_name, image_type) if process.returncode == 0: - flash('Attached '+ file_name + " to scsi id " + scsi_id + "!") - return redirect(url_for('index')) + flash("Attached " + file_name + " to scsi id " + scsi_id + "!") + return redirect(url_for("index")) else: - flash(u'Failed to attach '+ file_name + " to scsi id " + scsi_id + "!", 'error') - flash(process.stdout.decode("utf-8"), 'stdout') - flash(process.stderr.decode("utf-8"), 'stderr') - return redirect(url_for('index')) + flash( + u"Failed to attach " + file_name + " to scsi id " + scsi_id + "!", "error" + ) + flash(process.stdout.decode("utf-8"), "stdout") + flash(process.stderr.decode("utf-8"), "stderr") + return redirect(url_for("index")) -@app.route('/scsi/detach', methods=['POST']) +@app.route("/scsi/detach", methods=["POST"]) def detach(): - scsi_id = request.form.get('scsi_id') + scsi_id = request.form.get("scsi_id") process = detach_by_id(scsi_id) if process.returncode == 0: flash("Detached scsi id " + scsi_id + "!") - return redirect(url_for('index')) + return redirect(url_for("index")) else: - flash(u"Failed to detach scsi id " + scsi_id + "!", 'error') - flash(process.stdout, 'stdout') - flash(process.stderr, 'stderr') - return redirect(url_for('index')) + flash(u"Failed to detach scsi id " + scsi_id + "!", "error") + flash(process.stdout, "stdout") + flash(process.stderr, "stderr") + return redirect(url_for("index")) -@app.route('/scsi/eject', methods=['POST']) +@app.route("/scsi/eject", methods=["POST"]) def eject(): - scsi_id = request.form.get('scsi_id') + scsi_id = request.form.get("scsi_id") process = eject_by_id(scsi_id) if process.returncode == 0: flash("Ejected scsi id " + scsi_id + "!") - return redirect(url_for('index')) + return redirect(url_for("index")) else: - flash(u"Failed to eject scsi id " + scsi_id + "!", 'error') - flash(process.stdout, 'stdout') - flash(process.stderr, 'stderr') - return redirect(url_for('index')) + flash(u"Failed to eject scsi id " + scsi_id + "!", "error") + flash(process.stdout, "stdout") + flash(process.stderr, "stderr") + return redirect(url_for("index")) -@app.route('/pi/reboot', methods=['POST']) +@app.route("/pi/reboot", methods=["POST"]) def restart(): reboot_pi() flash("Restarting...") - return redirect(url_for('index')) + return redirect(url_for("index")) -@app.route('/rascsi/restart', methods=['POST']) +@app.route("/rascsi/restart", methods=["POST"]) def rascsi_restart(): rascsi_service("restart") flash("Restarting RaSCSI Service...") - return redirect(url_for('index')) + return redirect(url_for("index")) -@app.route('/pi/shutdown', methods=['POST']) +@app.route("/pi/shutdown", methods=["POST"]) def shutdown(): shutdown_pi() flash("Shutting down...") - return redirect(url_for('index')) + return redirect(url_for("index")) -@app.route('/files/download_to_iso', methods=['POST']) +@app.route("/files/download_to_iso", methods=["POST"]) def download_file(): - scsi_id = request.form.get('scsi_id') - url = request.form.get('url') + scsi_id = request.form.get("scsi_id") + url = request.form.get("url") process = download_file_to_iso(scsi_id, url) if process.returncode == 0: flash("File Downloaded") - return redirect(url_for('index')) + return redirect(url_for("index")) else: - flash(u"Failed to download file", 'error') - flash(process.stdout, 'stdout') - flash(process.stderr, 'stderr') - return redirect(url_for('index')) + flash(u"Failed to download file", "error") + flash(process.stdout, "stdout") + flash(process.stderr, "stderr") + return redirect(url_for("index")) -@app.route('/files/download_image', methods=['POST']) +@app.route("/files/download_image", methods=["POST"]) def download_img(): - url = request.form.get('url') + url = request.form.get("url") # TODO: error handling download_image(url) flash("File Downloaded") - return redirect(url_for('index')) + return redirect(url_for("index")) -@app.route('/files/upload', methods=['POST']) +@app.route("/files/upload", methods=["POST"]) def upload_file(): - if 'file' not in request.files: - flash('No file part', 'error') - return redirect(url_for('index')) - file = request.files['file'] + if "file" not in request.files: + flash("No file part", "error") + return redirect(url_for("index")) + file = request.files["file"] if file: filename = secure_filename(file.filename) - file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) - return redirect(url_for('index', filename=filename)) + file.save(os.path.join(app.config["UPLOAD_FOLDER"], filename)) + return redirect(url_for("index", filename=filename)) -@app.route('/files/create', methods=['POST']) +@app.route("/files/create", methods=["POST"]) def create_file(): - file_name = request.form.get('file_name') - size = request.form.get('size') - type = request.form.get('type') + file_name = request.form.get("file_name") + size = request.form.get("size") + type = request.form.get("type") process = create_new_image(file_name, type, size) if process.returncode == 0: flash("Drive created") - return redirect(url_for('index')) + return redirect(url_for("index")) else: - flash(u"Failed to create file", 'error') - flash(process.stdout, 'stdout') - flash(process.stderr, 'stderr') - return redirect(url_for('index')) + flash(u"Failed to create file", "error") + flash(process.stdout, "stdout") + flash(process.stderr, "stderr") + return redirect(url_for("index")) -@app.route('/files/download', methods=['POST']) +@app.route("/files/download", methods=["POST"]) def download(): - image = request.form.get('image') + image = request.form.get("image") return send_file(base_dir + image, as_attachment=True) -@app.route('/files/delete', methods=['POST']) +@app.route("/files/delete", methods=["POST"]) def delete(): - image = request.form.get('image') + image = request.form.get("image") if delete_image(image): flash("File " + image + " deleted") - return redirect(url_for('index')) + return redirect(url_for("index")) else: - flash(u"Failed to Delete " + image, 'error') - return redirect(url_for('index')) + flash(u"Failed to Delete " + image, "error") + return redirect(url_for("index")) -@app.route('/files/unzip', methods=['POST']) +@app.route("/files/unzip", methods=["POST"]) def unzip(): - image = request.form.get('image') + image = request.form.get("image") if unzip_file(image): flash("Unzipped file " + image) - return redirect(url_for('index')) + return redirect(url_for("index")) else: - flash(u"Failed to unzip " + image, 'error') - return redirect(url_for('index')) + flash(u"Failed to unzip " + image, "error") + return redirect(url_for("index")) if __name__ == "__main__": - app.secret_key = 'rascsi_is_awesome_insecure_secret_key' - app.config['SESSION_TYPE'] = 'filesystem' - app.config['UPLOAD_FOLDER'] = base_dir - os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) - app.config['MAX_CONTENT_LENGTH'] = MAX_FILE_SIZE + app.secret_key = "rascsi_is_awesome_insecure_secret_key" + app.config["SESSION_TYPE"] = "filesystem" + app.config["UPLOAD_FOLDER"] = base_dir + os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True) + app.config["MAX_CONTENT_LENGTH"] = MAX_FILE_SIZE from waitress import serve + serve(app, host="0.0.0.0", port=8080) From 0b78f09f8dee79c75d705d034551d85f4642107f Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Mon, 1 Feb 2021 12:24:59 -0600 Subject: [PATCH 15/22] Add DaynaPORT config to web Add bridge-utils Minor fixes to easyinstall Can now save config, detach all devices Bridge script error out if any command fails --- .gitignore | 3 + easyinstall.sh | 20 +++++-- src/raspberrypi/setup_bridge.sh | 1 + src/web/file_cmds.py | 2 +- src/web/mock/bin/brctl | 12 ++++ src/web/mock/bin/ip | 12 ++++ src/web/ractl_cmds.py | 46 ++++++++++++++- src/web/templates/index.html | 47 ++++++++++++++- src/web/web.py | 100 +++++++++++++++++++++++++++----- 9 files changed, 216 insertions(+), 27 deletions(-) create mode 100644 src/web/mock/bin/brctl create mode 100644 src/web/mock/bin/ip diff --git a/.gitignore b/.gitignore index 995e1e8a..7b05f121 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ venv *.pyc core +.idea/ +.DS_Store +*.swp diff --git a/easyinstall.sh b/easyinstall.sh index a3701188..811adda9 100755 --- a/easyinstall.sh +++ b/easyinstall.sh @@ -28,7 +28,7 @@ LIDO_DRIVER=~/RASCSI/lido-driver.img function initialChecks() { currentUser=$(whoami) - if [ "pi" != $currentUser ]; then + if [ "pi" != "$currentUser" ]; then echo "You must use 'pi' user (current: $currentUser)" exit 1 fi @@ -40,10 +40,14 @@ function initialChecks() { fi } +function installPackages() { + sudo apt-get update && sudo apt install git libspdlog-dev genisoimage python3 python3-venv nginx bridge-utils -y +} # install all dependency packages for RaSCSI Service # compile and install RaSCSI Service function installRaScsi() { + installPackages sudo apt-get update && sudo apt-get install --yes git libspdlog-dev cd ~/RASCSI/src/raspberrypi @@ -69,7 +73,7 @@ www-data ALL=NOPASSWD: /sbin/shutdown, /sbin/reboot function stopOldWebInterface() { APACHE_STATUS=$(sudo systemctl status apache2 &> /dev/null; echo $?) - if [ $APACHE_STATUS -eq 0 ] ; then + if [ "$APACHE_STATUS" -eq 0 ] ; then echo "Stopping old Apache2 RaSCSI Web..." sudo systemctl disable apache2 sudo systemctl stop apache2 @@ -79,7 +83,7 @@ function stopOldWebInterface() { # install everything required to run an HTTP server (Nginx + Python Flask App) function installRaScsiWebInterface() { stopOldWebInterface - sudo apt install genisoimage python3 python3-venv nginx -y + installPackages sudo cp -f ~/RASCSI/src/web/service-infra/nginx-default.conf /etc/nginx/sites-available/default sudo cp -f ~/RASCSI/src/web/service-infra/502.html /var/www/html/502.html @@ -100,11 +104,15 @@ function installRaScsiWebInterface() { function updateRaScsiGit() { cd ~/RASCSI - git pull + git fetch + git stash + git rebase origin/master + git stash apply } function updateRaScsi() { updateRaScsiGit + installPackages sudo systemctl stop rascsi cd ~/RASCSI/src/raspberrypi @@ -241,8 +249,8 @@ function showMenu() { choice=-1 until [ $choice -ge "0" ] && [ $choice -le "7" ]; do - echo "Enter your choice (0-7) or CTRL-C to exit" - read choice + echo -n "Enter your choice (0-7) or CTRL-C to exit: " + read -r choice done diff --git a/src/raspberrypi/setup_bridge.sh b/src/raspberrypi/setup_bridge.sh index d81e7358..936a4944 100755 --- a/src/raspberrypi/setup_bridge.sh +++ b/src/raspberrypi/setup_bridge.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e # Fail if any command fails sudo brctl addbr rascsi_bridge sudo brctl addif rascsi_bridge eth0 sudo ip link set dev rascsi_bridge up diff --git a/src/web/file_cmds.py b/src/web/file_cmds.py index 58512ed0..c424f82f 100644 --- a/src/web/file_cmds.py +++ b/src/web/file_cmds.py @@ -64,7 +64,7 @@ def download_file_to_iso(scsi_id, url): ) if iso_proc.returncode != 0: return iso_proc - return attach_image(scsi_id, iso_filename, "cd") + return attach_image(scsi_id, iso_filename, "SCCD") def download_image(url): diff --git a/src/web/mock/bin/brctl b/src/web/mock/bin/brctl new file mode 100644 index 00000000..176fe42d --- /dev/null +++ b/src/web/mock/bin/brctl @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# Mock responses to rascsi-web +case $1 in + "show") + echo "rascsi_bridge 8000.dca632b05dd1 no eth0" + ;; + + **) + echo "default" + ;; +esac diff --git a/src/web/mock/bin/ip b/src/web/mock/bin/ip new file mode 100644 index 00000000..259dc4b6 --- /dev/null +++ b/src/web/mock/bin/ip @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# Mock responses to rascsi-web +case $1 in + "link") + echo "link here" + ;; + + **) + echo "default" + ;; +esac diff --git a/src/web/ractl_cmds.py b/src/web/ractl_cmds.py index 60205903..fbc9cef5 100644 --- a/src/web/ractl_cmds.py +++ b/src/web/ractl_cmds.py @@ -37,6 +37,15 @@ def list_files(): return files_list +def list_config_files(): + files_list = [] + for root, dirs, files in os.walk(base_dir): + for file in files: + if file.endswith(".csv"): + files_list.append(file) + return files_list + + def get_valid_scsi_ids(devices): invalid_list = EXCLUDE_SCSI_IDS.copy() for device in devices: @@ -55,12 +64,16 @@ def get_type(scsi_id): return list_devices()[int(scsi_id)]["type"] -def attach_image(scsi_id, image, type): - if type == "cd" and get_type(scsi_id) == "SCCD": +def attach_image(scsi_id, image, device_type): + if device_type == "SCCD" and get_type(scsi_id) == "SCCD": return insert(scsi_id, image) + elif device_type == "SCDP": + attach_daynaport(scsi_id) else: + if device_type == "SCCD": + device_type = "cd" return subprocess.run( - ["rasctl", "-c", "attach", "-t", type, "-i", scsi_id, "-f", image], + ["rasctl", "-c", "attach", "-t", device_type, "-i", scsi_id, "-f", image], capture_output=True, ) @@ -69,6 +82,11 @@ def detach_by_id(scsi_id): return subprocess.run(["rasctl", "-c" "detach", "-i", scsi_id], capture_output=True) +def detach_all(): + for scsi_id in range(0, 7): + subprocess.run(["rasctl", "-c" "detach", "-i", str(scsi_id)]) + + def disconnect_by_id(scsi_id): return subprocess.run( ["rasctl", "-c", "disconnect", "-i", scsi_id], capture_output=True @@ -85,6 +103,28 @@ def insert(scsi_id, image): ) +def attach_daynaport(scsi_id): + return subprocess.run( + ["rasctl", "-i", scsi_id, "-c", "attach", "-t", "daynaport"], + capture_output=True, + ) + + +def is_bridge_setup(interface): + process = subprocess.run(["brctl", "show"], capture_output=True) + output = process.stdout.decode("utf-8") + if "rascsi_bridge" in output and interface in output: + return True + return False + + +def daynaport_setup_bridge(interface): + return subprocess.run( + [f"{base_dir}../RASCSI/src/raspberrypi/setup_bridge.sh", interface], + capture_output=True, + ) + + def rascsi_service(action): # start/stop/restart return ( diff --git a/src/web/templates/index.html b/src/web/templates/index.html index a11fab57..d7bbccdd 100644 --- a/src/web/templates/index.html +++ b/src/web/templates/index.html @@ -17,10 +17,26 @@ - {% endblock %} +{% endblock %} {% block content %}

Current RaSCSI Configuration

+
+ + +
+
+ + +
+
+ +
+ @@ -103,7 +119,35 @@

+

Attach Ethernet Adapter

+

Emulates a SCSI DaynaPORT Ethernet Adapter. Host drivers required.

+ + + + + + + +
+
+ + +
+
+ {% if bridge_configured %} + Bridge is currently configured! + {% else %} +
+ +
+ {% endif %} +
+

Upload File

Uploads file to {{base_dir}}. Max file size is set to {{max_file_size / 1024 /1024 }}MB

@@ -183,7 +227,6 @@

-

Raspberry Pi Operations

diff --git a/src/web/web.py b/src/web/web.py index 0fe3a20f..2268d43d 100644 --- a/src/web/web.py +++ b/src/web/web.py @@ -1,5 +1,3 @@ -import os - from flask import Flask, render_template, request, flash, url_for, redirect, send_file from werkzeug.utils import secure_filename @@ -19,6 +17,11 @@ from ractl_cmds import ( detach_by_id, eject_by_id, get_valid_scsi_ids, + attach_daynaport, + is_bridge_setup, + daynaport_setup_bridge, + list_config_files, + detach_all, ) from settings import * @@ -31,9 +34,11 @@ def index(): scsi_ids = get_valid_scsi_ids(devices) return render_template( "index.html", + bridge_configured=is_bridge_setup("eth0"), devices=devices, active=is_active(), files=list_files(), + config_files=list_config_files(), base_dir=base_dir, scsi_ids=scsi_ids, max_file_size=MAX_FILE_SIZE, @@ -41,6 +46,37 @@ def index(): ) +@app.route("/config/save", methods=["POST"]) +def config_save(): + file_name = request.form.get("name") or "default" + file_name = f"{base_dir}{file_name}.csv" + import csv + + with open(file_name, "w") as csv_file: + writer = csv.writer(csv_file) + for device in list_devices(): + if device["type"] is not "-": + writer.writerow(device.values()) + flash(f"Saved config to {file_name}!") + return redirect(url_for("index")) + + +@app.route("/config/load", methods=["POST"]) +def config_load(): + file_name = request.form.get("name") or "default.csv" + file_name = f"{base_dir}{file_name}" + detach_all() + import csv + + with open(file_name) as csv_file: + config_reader = csv.reader(csv_file) + for row in config_reader: + image_name = row[3].replace("(WRITEPROTECT)", "") + attach_image(row[0], image_name, row[2]) + flash(f"Loaded config from {file_name}!") + return redirect(url_for("index")) + + @app.route("/logs") def logs(): import subprocess @@ -52,7 +88,36 @@ def logs(): headers = {"content-type": "text/plain"} return process.stdout.decode("utf-8"), 200, headers else: - flash(u"Failed to get logs") + flash("Failed to get logs") + flash(process.stdout.decode("utf-8"), "stdout") + flash(process.stderr.decode("utf-8"), "stderr") + return redirect(url_for("index")) + + +@app.route("/daynaport/attach", methods=["POST"]) +def daynaport_attach(): + scsi_id = request.form.get("scsi_id") + process = attach_daynaport(scsi_id) + if process.returncode == 0: + flash(f"Attached DaynaPORT to SCSI id {scsi_id}!") + return redirect(url_for("index")) + else: + flash(f"Failed to attach DaynaPORT to SCSI id {scsi_id}!", "error") + flash(process.stdout.decode("utf-8"), "stdout") + flash(process.stderr.decode("utf-8"), "stderr") + return redirect(url_for("index")) + + +@app.route("/daynaport/setup", methods=["POST"]) +def daynaport_setup(): + # Future use for wifi + interface = request.form.get("interface") or "eth0" + process = daynaport_setup_bridge(interface) + if process.returncode == 0: + flash(f"Configured DaynaPORT bridge on {interface}!") + return redirect(url_for("index")) + else: + flash(f"Failed to configure DaynaPORT bridge on {interface}!", "error") flash(process.stdout.decode("utf-8"), "stdout") flash(process.stderr.decode("utf-8"), "stderr") return redirect(url_for("index")) @@ -69,31 +134,36 @@ def attach(): elif file_name.lower().endswith(".hda"): image_type = "hd" else: - flash(u"Unknown file type. Valid files are .iso, .hda, .cdr", "error") + flash("Unknown file type. Valid files are .iso, .hda, .cdr", "error") return redirect(url_for("index")) process = attach_image(scsi_id, file_name, image_type) if process.returncode == 0: - flash("Attached " + file_name + " to scsi id " + scsi_id + "!") + flash(f"Attached {file_name} to SCSI id {scsi_id}!") return redirect(url_for("index")) else: - flash( - u"Failed to attach " + file_name + " to scsi id " + scsi_id + "!", "error" - ) + flash(f"Failed to attach {file_name} to SCSI id {scsi_id}!", "error") flash(process.stdout.decode("utf-8"), "stdout") flash(process.stderr.decode("utf-8"), "stderr") return redirect(url_for("index")) +@app.route("/scsi/detach_all", methods=["POST"]) +def detach_all_devices(): + detach_all() + flash("Detached all SCSI devices!") + return redirect(url_for("index")) + + @app.route("/scsi/detach", methods=["POST"]) def detach(): scsi_id = request.form.get("scsi_id") process = detach_by_id(scsi_id) if process.returncode == 0: - flash("Detached scsi id " + scsi_id + "!") + flash("Detached SCSI id " + scsi_id + "!") return redirect(url_for("index")) else: - flash(u"Failed to detach scsi id " + scsi_id + "!", "error") + flash("Failed to detach SCSI id " + scsi_id + "!", "error") flash(process.stdout, "stdout") flash(process.stderr, "stderr") return redirect(url_for("index")) @@ -107,7 +177,7 @@ def eject(): flash("Ejected scsi id " + scsi_id + "!") return redirect(url_for("index")) else: - flash(u"Failed to eject scsi id " + scsi_id + "!", "error") + flash("Failed to eject SCSI id " + scsi_id + "!", "error") flash(process.stdout, "stdout") flash(process.stderr, "stderr") return redirect(url_for("index")) @@ -143,7 +213,7 @@ def download_file(): flash("File Downloaded") return redirect(url_for("index")) else: - flash(u"Failed to download file", "error") + flash("Failed to download file", "error") flash(process.stdout, "stdout") flash(process.stderr, "stderr") return redirect(url_for("index")) @@ -181,7 +251,7 @@ def create_file(): flash("Drive created") return redirect(url_for("index")) else: - flash(u"Failed to create file", "error") + flash("Failed to create file", "error") flash(process.stdout, "stdout") flash(process.stderr, "stderr") return redirect(url_for("index")) @@ -200,7 +270,7 @@ def delete(): flash("File " + image + " deleted") return redirect(url_for("index")) else: - flash(u"Failed to Delete " + image, "error") + flash("Failed to Delete " + image, "error") return redirect(url_for("index")) @@ -212,7 +282,7 @@ def unzip(): flash("Unzipped file " + image) return redirect(url_for("index")) else: - flash(u"Failed to unzip " + image, "error") + flash("Failed to unzip " + image, "error") return redirect(url_for("index")) From 852f4f11fd21bd4f2f291b626ee5a351b6ee5780 Mon Sep 17 00:00:00 2001 From: akuker <34318535+akuker@users.noreply.github.com> Date: Tue, 2 Feb 2021 19:55:38 -0600 Subject: [PATCH 16/22] Revert "Add Daynaport SCSI/Link Functionality" (#78) --- .gitignore | 2 - src/raspberrypi/.vscode/launch.json | 4 +- src/raspberrypi/.vscode/tasks.json | 2 +- src/raspberrypi/Makefile | 12 +- src/raspberrypi/controllers/sasidev_ctrl.cpp | 483 ++++++++------- src/raspberrypi/controllers/sasidev_ctrl.h | 16 +- src/raspberrypi/controllers/scsidev_ctrl.cpp | 550 ++++++++---------- src/raspberrypi/controllers/scsidev_ctrl.h | 79 +-- src/raspberrypi/devices/ctapdriver.cpp | 137 +---- src/raspberrypi/devices/ctapdriver.h | 12 +- src/raspberrypi/devices/disk.cpp | 53 +- src/raspberrypi/devices/disk.h | 14 +- src/raspberrypi/devices/scsi_daynaport.cpp | 540 ----------------- src/raspberrypi/devices/scsi_daynaport.h | 199 ------- src/raspberrypi/devices/scsicd.cpp | 4 +- src/raspberrypi/devices/scsicd.h | 4 +- src/raspberrypi/devices/scsihd.cpp | 4 +- src/raspberrypi/gpiobus.h | 26 +- src/raspberrypi/launch_sudo.sh | 3 - src/raspberrypi/log.h | 48 +- src/raspberrypi/os.cpp | 35 -- src/raspberrypi/os.h | 10 +- src/raspberrypi/os_integration/rascsi.service | 2 +- src/raspberrypi/rascsi.cpp | 82 +-- src/raspberrypi/rasctl.cpp | 25 +- src/raspberrypi/rasctl.h | 24 - src/raspberrypi/rasdump.cpp | 219 ++++--- src/raspberrypi/scsi.h | 92 +-- src/raspberrypi/setup_bridge.sh | 7 - 29 files changed, 748 insertions(+), 1940 deletions(-) delete mode 100644 src/raspberrypi/devices/scsi_daynaport.cpp delete mode 100644 src/raspberrypi/devices/scsi_daynaport.h delete mode 100755 src/raspberrypi/launch_sudo.sh delete mode 100644 src/raspberrypi/os.cpp delete mode 100644 src/raspberrypi/rasctl.h delete mode 100755 src/raspberrypi/setup_bridge.sh diff --git a/.gitignore b/.gitignore index 995e1e8a..5ceb3864 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ venv -*.pyc -core diff --git a/src/raspberrypi/.vscode/launch.json b/src/raspberrypi/.vscode/launch.json index b58c19b7..4ac5ab4b 100644 --- a/src/raspberrypi/.vscode/launch.json +++ b/src/raspberrypi/.vscode/launch.json @@ -8,15 +8,13 @@ "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/bin/fullspec/rascsi", + "program": "${workspaceFolder}/bin/rascsi", "args": [], "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", - "targetArchitecture": "arm", - "miDebuggerPath": "${workspaceFolder}/launch_sudo.sh", "setupCommands": [ { "description": "Enable pretty-printing for gdb", diff --git a/src/raspberrypi/.vscode/tasks.json b/src/raspberrypi/.vscode/tasks.json index 850ac6dd..eeedfe8a 100644 --- a/src/raspberrypi/.vscode/tasks.json +++ b/src/raspberrypi/.vscode/tasks.json @@ -5,7 +5,7 @@ "type": "shell", "label": "g++ build active file", "command": "make", - "args": ["all", "DEBUG=1", "-j4"], + "args": ["all", "DEBUG=1"], "options": { "cwd": "${workspaceFolder}/" }, diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 9a9984be..34d421a4 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -33,9 +33,9 @@ endif CFLAGS += -iquote . -MD -MP CXXFLAGS += -std=c++14 -iquote . -MD -MP -## CONNECT_TYPE=FULLSPEC : Specify the type of RaSCSI board type +## CONNECT_TYPE=STANDARD : Specify the type of RaSCSI board type ## that you are using. The typical options are -## STANDARD or FULLSPEC. The default is FULLSPEC +## STANDARD or FULLSPEC. The default is STANDARD ## * THIS IS TYPICALLY THE ONLY COMPILE OPTION YOU ## * NEED TO SPECIFY # If its not specified, build for FULLSPEC configuration @@ -75,7 +75,6 @@ SRC_RASCSI = \ gpiobus.cpp \ filepath.cpp \ fileio.cpp\ - os.cpp\ rascsi_version.cpp # os.cpp # rasctl_command.cpp @@ -89,8 +88,11 @@ SRC_SCSIMON = \ scsi.cpp \ gpiobus.cpp \ filepath.cpp \ - fileio.cpp \ + fileio.cpp\ rascsi_version.cpp +SRC_SCSIMON += $(shell find ./controllers -name '*.cpp') +SRC_SCSIMON += $(shell find ./devices -name '*.cpp') + SRC_RASCTL = \ rasctl.cpp\ @@ -152,7 +154,7 @@ ALL: all docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt $(BINDIR)/$(RASCSI): $(OBJ_RASCSI) | $(BINDIR) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread -lz + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread $(BINDIR)/$(RASCTL): $(OBJ_RASCTL) | $(BINDIR) $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL) diff --git a/src/raspberrypi/controllers/sasidev_ctrl.cpp b/src/raspberrypi/controllers/sasidev_ctrl.cpp index 6fc5987c..0cd1f420 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.cpp +++ b/src/raspberrypi/controllers/sasidev_ctrl.cpp @@ -17,8 +17,6 @@ #include "filepath.h" #include "gpiobus.h" #include "devices/scsi_host_bridge.h" -#include "controllers/scsidev_ctrl.h" -#include "devices/scsi_daynaport.h" //=========================================================================== // @@ -46,7 +44,7 @@ SASIDEV::SASIDEV(Device *dev) // Work initialization ctrl.phase = BUS::busfree; - ctrl.m_scsi_id = -1; + ctrl.id = -1; ctrl.bus = NULL; memset(ctrl.cmd, 0x00, sizeof(ctrl.cmd)); ctrl.status = 0x00; @@ -54,7 +52,7 @@ SASIDEV::SASIDEV(Device *dev) #ifdef RASCSI ctrl.execstart = 0; #endif // RASCSI - ctrl.bufsize = ETH_FRAME_LEN + 16 + ETH_FCS_LEN; + ctrl.bufsize = 0x800; ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); memset(ctrl.buffer, 0x00, ctrl.bufsize); ctrl.blocks = 0; @@ -203,7 +201,7 @@ void FASTCALL SASIDEV::Connect(int id, BUS *bus) { ASSERT(this); - ctrl.m_scsi_id = id; + ctrl.id = id; ctrl.bus = bus; } @@ -293,7 +291,7 @@ BUS::phase_t FASTCALL SASIDEV::Process() ASSERT(this); // Do nothing if not connected - if (ctrl.m_scsi_id < 0 || ctrl.bus == NULL) { + if (ctrl.id < 0 || ctrl.bus == NULL) { return ctrl.phase; } @@ -303,7 +301,9 @@ BUS::phase_t FASTCALL SASIDEV::Process() // For the monitor tool, we shouldn't need to reset. We're just logging information // Reset if (ctrl.bus->GetRST()) { - LOGINFO("RESET signal received"); +#if defined(DISK_LOG) + Log(Log::Normal, "RESET signal received"); +#endif // DISK_LOG // Reset the controller Reset(); @@ -371,7 +371,9 @@ void FASTCALL SASIDEV::BusFree() // Phase change if (ctrl.phase != BUS::busfree) { - LOGINFO("Bus free phase"); +#if defined(DISK_LOG) + Log(Log::Normal, "Bus free phase"); +#endif // DISK_LOG // Phase Setting ctrl.phase = BUS::busfree; @@ -409,7 +411,7 @@ void FASTCALL SASIDEV::Selection() // Phase change if (ctrl.phase != BUS::selection) { // Invalid if IDs do not match - id = 1 << ctrl.m_scsi_id; + id = 1 << ctrl.id; if ((ctrl.bus->GetDAT() & id) == 0) { return; } @@ -419,7 +421,10 @@ void FASTCALL SASIDEV::Selection() return; } - LOGTRACE("%s Selection Phase ID=%d (with device)", __PRETTY_FUNCTION__, (int)ctrl.m_scsi_id); +#if defined(DISK_LOG) + Log(Log::Normal, + "Selection Phase ID=%d (with device)", ctrl.id); +#endif // DISK_LOG // Phase change ctrl.phase = BUS::selection; @@ -452,7 +457,9 @@ void FASTCALL SASIDEV::Command() // Phase change if (ctrl.phase != BUS::command) { - LOGTRACE("%s Command Phase", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "Command Phase"); +#endif // DISK_LOG // Phase Setting ctrl.phase = BUS::command; @@ -530,7 +537,9 @@ void FASTCALL SASIDEV::Execute() { ASSERT(this); - LOGTRACE("%s Execution Phase Command %02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[0]); +#if defined(DISK_LOG) + Log(Log::Normal, "Execution Phase Command %02X", ctrl.cmd[0]); +#endif // DISK_LOG // Phase Setting ctrl.phase = BUS::execute; @@ -543,68 +552,65 @@ void FASTCALL SASIDEV::Execute() #endif // RASCSI // Process by command - switch ((SCSIDEV::scsi_command)ctrl.cmd[0]) { + switch (ctrl.cmd[0]) { // TEST UNIT READY - case SCSIDEV::eCmdTestUnitReady: + case 0x00: CmdTestUnitReady(); return; // REZERO UNIT - case SCSIDEV::eCmdRezero: + case 0x01: CmdRezero(); return; // REQUEST SENSE - case SCSIDEV::eCmdRequestSense: + case 0x03: CmdRequestSense(); return; // FORMAT UNIT - // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. - // leaving it here for now.... - case SCSIDEV::eCmdFormat: + case 0x04: + CmdFormat(); + return; + + // FORMAT UNIT + case 0x06: CmdFormat(); return; // REASSIGN BLOCKS - case SCSIDEV::eCmdReassign: + case 0x07: CmdReassign(); return; // READ(6) - case SCSIDEV::eCmdRead6: + case 0x08: CmdRead6(); return; // WRITE(6) - case SCSIDEV::eCmdWrite6: + case 0x0a: CmdWrite6(); return; // SEEK(6) - case SCSIDEV::eCmdSeek6: + case 0x0b: CmdSeek6(); return; // ASSIGN(SASIのみ) - // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. - // leaving it here for now.... - case SCSIDEV::eCmdSasiCmdAssign: + case 0x0e: CmdAssign(); return; // SPECIFY(SASIのみ) - // This doesn't exist in the SCSI Spec, but was in the original RaSCSI code. - // leaving it here for now.... - case SCSIDEV::eCmdInvalid: + case 0xc2: CmdSpecify(); return; - default: - break; } // Unsupported command - LOGWARN("%s Unsupported command $%02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[0]); + Log(Log::Warning, "Unsupported command $%02X", ctrl.cmd[0]); CmdInvalid(); } @@ -639,7 +645,9 @@ void FASTCALL SASIDEV::Status() } #endif // RASCSI - LOGTRACE("%s Status phase", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "Status phase"); +#endif // DISK_LOG // Phase Setting ctrl.phase = BUS::status; @@ -660,7 +668,9 @@ void FASTCALL SASIDEV::Status() ctrl.bus->SetDAT(ctrl.buffer[0]); ctrl.bus->SetREQ(TRUE); - LOGTRACE( "%s Status Phase $%02X",__PRETTY_FUNCTION__, (unsigned int)ctrl.status); +#if defined(DISK_LOG) + Log(Log::Normal, "Status Phase $%02X", ctrl.status); +#endif // DISK_LOG #endif // RASCSI return; } @@ -695,7 +705,10 @@ void FASTCALL SASIDEV::MsgIn() // Phase change if (ctrl.phase != BUS::msgin) { - LOGTRACE("%s Starting Message in phase", __PRETTY_FUNCTION__); + +#if defined(DISK_LOG) + Log(Log::Normal, "Message in phase"); +#endif // DISK_LOG // Phase Setting ctrl.phase = BUS::msgin; @@ -709,12 +722,36 @@ void FASTCALL SASIDEV::MsgIn() ASSERT(ctrl.length > 0); ASSERT(ctrl.blocks > 0); ctrl.offset = 0; + +#ifndef RASCSI + // Request message + ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); + ctrl.bus->SetREQ(TRUE); + +#if defined(DISK_LOG) + Log(Log::Normal, "Message in phase $%02X", ctrl.buffer[ctrl.offset]); +#endif // DISK_LOG +#endif // RASCSI return; } +#ifdef RASCSI //Send - LOGTRACE("%s Transitioning to Send()", __PRETTY_FUNCTION__); Send(); +#else + // Requesting + if (ctrl.bus->GetREQ()) { + // Initator received + if (ctrl.bus->GetACK()) { + SendNext(); + } + } else { + // Initiator requests next + if (!ctrl.bus->GetACK()) { + Send(); + } + } +#endif // RASCSI } //--------------------------------------------------------------------------- @@ -753,7 +790,10 @@ void FASTCALL SASIDEV::DataIn() return; } - LOGTRACE("%s Going into Data-in Phase", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "Data-in Phase"); +#endif // DISK_LOG + // Phase Setting ctrl.phase = BUS::datain; @@ -767,11 +807,33 @@ void FASTCALL SASIDEV::DataIn() ASSERT(ctrl.blocks > 0); ctrl.offset = 0; +#ifndef RASCSI + // Assert the DAT signal + ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); + + // Request data + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } +#ifdef RASCSI // Send Send(); +#else + // Requesting + if (ctrl.bus->GetREQ()) { + // Initator received + if (ctrl.bus->GetACK()) { + SendNext(); + } + } else { + // Initiator requests next + if (!ctrl.bus->GetACK()) { + Send(); + } + } +#endif // RASCSI } //--------------------------------------------------------------------------- @@ -810,7 +872,9 @@ void FASTCALL SASIDEV::DataOut() return; } - LOGTRACE("%s Data out phase", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "Data out phase"); +#endif // DISK_LOG // Phase Setting ctrl.phase = BUS::dataout; @@ -882,7 +946,7 @@ void FASTCALL SASIDEV::Error() } #if defined(DISK_LOG) - LOGWARN("Error occured (going to status phase)"); + Log(Log::Warning, "Error occured (going to status phase)"); #endif // DISK_LOG // Logical Unit @@ -907,7 +971,9 @@ void FASTCALL SASIDEV::CmdTestUnitReady() ASSERT(this); - LOGTRACE("%s TEST UNIT READY Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "TEST UNIT READY Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -940,7 +1006,9 @@ void FASTCALL SASIDEV::CmdRezero() ASSERT(this); - LOGTRACE( "%s REZERO UNIT Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "REZERO UNIT Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -972,7 +1040,9 @@ void FASTCALL SASIDEV::CmdRequestSense() ASSERT(this); - LOGTRACE( "%s REQUEST SENSE Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "REQUEST SENSE Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -981,11 +1051,13 @@ void FASTCALL SASIDEV::CmdRequestSense() return; } + // Command processing on drive ctrl.length = ctrl.unit[lun]->RequestSense(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length > 0); - - LOGTRACE("%s Sense key $%02X",__PRETTY_FUNCTION__, (WORD)ctrl.buffer[2]); +#if defined(DISK_LOG) + Log(Log::Normal, "Sense key $%02X", ctrl.buffer[2]); +#endif // DISK_LOG // Read phase DataIn(); @@ -1003,7 +1075,9 @@ void FASTCALL SASIDEV::CmdFormat() ASSERT(this); - LOGTRACE( "%s FORMAT UNIT Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "FORMAT UNIT Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1036,7 +1110,9 @@ void FASTCALL SASIDEV::CmdReassign() ASSERT(this); - LOGTRACE("%s REASSIGN BLOCKS Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "REASSIGN BLOCKS Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1087,82 +1163,13 @@ void FASTCALL SASIDEV::CmdRead6() ctrl.blocks = 0x100; } - if(ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'D', 'P')){ - // 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()); +#if defined(DISK_LOG) + Log(Log::Normal, + "READ(6) command record=%06X blocks=%d", record, ctrl.blocks); +#endif // DISK_LOG // 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'))) { - // Failure (Error) - Error(); - return; - } - - // Set next block - ctrl.next = record + 1; - - // Read phase - DataIn(); -} - - -//--------------------------------------------------------------------------- -// -// This Send Message command is used by the DaynaPort SCSI/Link -// -//--------------------------------------------------------------------------- -void FASTCALL SASIDEV::DaynaPortWrite() -{ - DWORD lun; - DWORD data_format; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Error if not a host bridge - if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')) { - LOGERROR("Received DaynaPortWrite for a non-DaynaPort device"); - Error(); - return; - } - - // Reallocate buffer (because it is not transfer for each block) - if (ctrl.bufsize < 0x1000000) { - free(ctrl.buffer); - ctrl.bufsize = 0x1000000; - ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); - } - - - data_format = ctrl.cmd[5]; - - - if(data_format == 0x00){ - ctrl.length = (WORD)ctrl.cmd[4] + ((WORD)ctrl.cmd[3] << 8); - } - else if (data_format == 0x80){ - ctrl.length = (WORD)ctrl.cmd[4] + ((WORD)ctrl.cmd[3] << 8) + 8; - } - else - { - LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)data_format); - } - LOGTRACE("%s length: %04X (%d) format: %02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.length, (int)ctrl.length, (unsigned int)data_format); - + ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record); if (ctrl.length <= 0) { // Failure (Error) Error(); @@ -1170,14 +1177,12 @@ void FASTCALL SASIDEV::DaynaPortWrite() } // Set next block - ctrl.blocks = 1; - ctrl.next = 1; + ctrl.next = record + 1; - // Light phase - DataOut(); + // Read phase + DataIn(); } - //--------------------------------------------------------------------------- // // WRITE(6) @@ -1197,12 +1202,6 @@ void FASTCALL SASIDEV::CmdWrite6() return; } - // Special receive function for the DaynaPort - if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'D', 'P')){ - DaynaPortWrite(); - return; - } - // Get record number and block number record = ctrl.cmd[1] & 0x1f; record <<= 8; @@ -1214,12 +1213,14 @@ void FASTCALL SASIDEV::CmdWrite6() ctrl.blocks = 0x100; } - LOGTRACE("%s WRITE(6) command record=%06X blocks=%d", __PRETTY_FUNCTION__, (WORD)record, (WORD)ctrl.blocks); +#if defined(DISK_LOG) + Log(Log::Normal, + "WRITE(6) command record=%06X blocks=%d", record, ctrl.blocks); +#endif // DISK_LOG // Command processing on drive ctrl.length = ctrl.unit[lun]->WriteCheck(record); if (ctrl.length <= 0) { - LOGDEBUG("WriteCheck failed"); // Failure (Error) Error(); return; @@ -1244,7 +1245,9 @@ void FASTCALL SASIDEV::CmdSeek6() ASSERT(this); - LOGTRACE("%s SEEK(6) Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "SEEK(6) Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1277,7 +1280,9 @@ void FASTCALL SASIDEV::CmdAssign() ASSERT(this); - LOGTRACE("%s ASSIGN Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "ASSIGN Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1313,7 +1318,9 @@ void FASTCALL SASIDEV::CmdSpecify() ASSERT(this); - LOGTRACE("%s SPECIFY Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "SPECIFY Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1347,7 +1354,10 @@ void FASTCALL SASIDEV::CmdInvalid() DWORD lun; ASSERT(this); - LOGWARN("%s Command not supported", __PRETTY_FUNCTION__); + +#if defined(DISK_LOG) + Log(Log::Normal, "Command not supported"); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1382,6 +1392,7 @@ void FASTCALL SASIDEV::Send() ASSERT(!ctrl.bus->GetREQ()); ASSERT(ctrl.bus->GetIO()); +#ifdef RASCSI // Check that the length isn't 0 if (ctrl.length != 0) { len = ctrl.bus->SendHandShake( @@ -1389,7 +1400,6 @@ void FASTCALL SASIDEV::Send() // If you can not send it all, move on to the status phase if (len != (int)ctrl.length) { - LOGERROR("%s ctrl.length (%d) did not match the amount of data sent (%d)",__PRETTY_FUNCTION__, (int)ctrl.length, len); Error(); return; } @@ -1399,9 +1409,20 @@ void FASTCALL SASIDEV::Send() ctrl.length = 0; return; } - else{ - LOGINFO("%s ctrl.length was 0", __PRETTY_FUNCTION__); +#else + // Offset and Length + ASSERT(ctrl.length >= 1); + ctrl.offset++; + ctrl.length--; + + // Immediately after ACK is asserted, if the data + // has been set by SendNext, raise the request + if (ctrl.length != 0) { + // Signal line operated by the target + ctrl.bus->SetREQ(TRUE); + return; } +#endif // RASCSI // Remove block and initialize the result ctrl.blocks--; @@ -1412,8 +1433,8 @@ void FASTCALL SASIDEV::Send() if (ctrl.blocks != 0) { // Set next buffer (set offset, length) result = XferIn(ctrl.buffer); - LOGTRACE("%s xfer in: %d",__PRETTY_FUNCTION__, result); - LOGTRACE("%s processing after data collection", __PRETTY_FUNCTION__); + //** printf("xfer in: %d \n",result); + #ifndef RASCSI ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); #endif // RASCSI @@ -1422,7 +1443,6 @@ void FASTCALL SASIDEV::Send() // If result FALSE, move to the status phase if (!result) { - LOGERROR("%s Send result was false", __PRETTY_FUNCTION__); Error(); return; } @@ -1518,7 +1538,9 @@ void FASTCALL SASIDEV::Receive() // Command phase case BUS::command: ctrl.cmd[ctrl.offset] = data; - LOGTRACE( "%s Command phase $%02X", __PRETTY_FUNCTION__, data); +#if defined(DISK_LOG) + Log(Log::Normal, "Command phase $%02X", data); +#endif // DISK_LOG // Set the length again with the first data (offset 0) if (ctrl.offset == 0) { @@ -1575,7 +1597,6 @@ void FASTCALL SASIDEV::ReceiveNext() // Receive len = ctrl.bus->ReceiveHandShake( &ctrl.buffer[ctrl.offset], ctrl.length); - LOGDEBUG("%s Received %d bytes", __PRETTY_FUNCTION__, len); // If not able to receive all, move to status phase if (len != (int)ctrl.length) { @@ -1588,10 +1609,6 @@ void FASTCALL SASIDEV::ReceiveNext() ctrl.length = 0; return; } - else - { - LOGDEBUG("%s ctrl.length was 0", __PRETTY_FUNCTION__); - } #else // Offset and Length ASSERT(ctrl.length >= 1); @@ -1650,7 +1667,6 @@ void FASTCALL SASIDEV::ReceiveNext() // Data out phase case BUS::dataout: - LOGTRACE("%s transitioning to FlushUnit()",__PRETTY_FUNCTION__); // Flush FlushUnit(); @@ -1677,7 +1693,6 @@ BOOL FASTCALL SASIDEV::XferIn(BYTE *buf) ASSERT(this); ASSERT(ctrl.phase == BUS::datain); - LOGTRACE("%s ctrl.cmd[0]=%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[0]); // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1692,7 +1707,7 @@ BOOL FASTCALL SASIDEV::XferIn(BYTE *buf) // READ(10) case 0x28: // Read from disk - ctrl.length = ctrl.unit[lun]->Read(ctrl.cmd, buf, ctrl.next); + ctrl.length = ctrl.unit[lun]->Read(buf, ctrl.next); ctrl.next++; // If there is an error, go to the status phase @@ -1735,9 +1750,12 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) return FALSE; } - switch ((SCSIDEV::scsi_command) ctrl.cmd[0]) { - case SCSIDEV::eCmdModeSelect: - case SCSIDEV::eCmdModeSelect10: + // MODE SELECT or WRITE system + switch (ctrl.cmd[0]) { + // MODE SELECT + case 0x15: + // MODE SELECT(10) + case 0x55: if (!ctrl.unit[lun]->ModeSelect( ctrl.cmd, ctrl.buffer, ctrl.offset)) { // MODE SELECT failed @@ -1745,11 +1763,11 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) } break; - case SCSIDEV::eCmdWrite6: - case SCSIDEV::eCmdWrite10: - case SCSIDEV::eCmdWriteAndVerify10: - // If we're a host bridge, use the host bridge's SendMessage10 - // function + // WRITE(6) + case 0x0a: + // WRITE(10) + case 0x2a: + // Replace the host bridge with SEND MESSAGE 10 if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) { bridge = (SCSIBR*)ctrl.unit[lun]; if (!bridge->SendMessage10(ctrl.cmd, ctrl.buffer)) { @@ -1762,23 +1780,10 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) break; } - // Special case Write function for DaynaPort - if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'D', 'P')) { - LOGTRACE("%s Doing special case write for DayanPort", __PRETTY_FUNCTION__); - if (!(SCSIDaynaPort*)ctrl.unit[lun]->Write(ctrl.cmd, ctrl.buffer, ctrl.length)) { - // write failed - return FALSE; - } - LOGTRACE("%s Done with DaynaPort Write", __PRETTY_FUNCTION__); - - // If normal, work setting - ctrl.offset = 0; - ctrl.blocks = 0; - break; - } - - LOGTRACE("%s eCmdWriteAndVerify10 Calling Write... cmd: %02X next: %d", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd, (int)ctrl.next); - if (!ctrl.unit[lun]->Write(ctrl.cmd, ctrl.buffer, ctrl.next - 1)) { + // WRITE AND VERIFY + case 0x2e: + // Write + if (!ctrl.unit[lun]->Write(ctrl.buffer, ctrl.next - 1)) { // Write failed return FALSE; } @@ -1801,14 +1806,10 @@ BOOL FASTCALL SASIDEV::XferOut(BOOL cont) break; // SPECIFY(SASI only) - case SCSIDEV::eCmdInvalid: + case 0xc2: break; - case SCSIDEV::eCmdSetMcastAddr: - LOGTRACE("%s Done with DaynaPort Set Multicast Address", __PRETTY_FUNCTION__); - break; default: - LOGWARN("Received an unexpected command (%02X) in %s", (WORD)ctrl.cmd[0] , __PRETTY_FUNCTION__) ASSERT(FALSE); break; } @@ -1836,49 +1837,45 @@ void FASTCALL SASIDEV::FlushUnit() } // WRITE system only - switch ((SCSIDEV::scsi_command)ctrl.cmd[0]) { - case SCSIDEV::eCmdWrite6: - case SCSIDEV::eCmdWrite10: - case SCSIDEV::eCmdWriteAndVerify10: + switch (ctrl.cmd[0]) { + // WRITE(6) + case 0x0a: + // WRITE(10) + case 0x2a: + // WRITE AND VERIFY + case 0x2e: // Flush if (!ctrl.unit[lun]->IsCacheWB()) { ctrl.unit[lun]->Flush(); } break; - case SCSIDEV::eCmdModeSelect: - case SCSIDEV::eCmdModeSelect10: + // Mode Select (6) + case 0x15: + // MODE SELECT(10) + case 0x55: // Debug code related to Issue #2 on github, where we get an unhandled Model select when // the mac is rebooted // https://github.com/akuker/RASCSI/issues/2 - LOGWARN("Received \'Mode Select\'\n"); - LOGWARN(" Operation Code: [%02X]\n", (WORD)ctrl.cmd[0]); - LOGWARN(" Logical Unit %01X, PF %01X, SP %01X [%02X]\n",\ - (WORD)ctrl.cmd[1] >> 5, 1 & ((WORD)ctrl.cmd[1] >> 4), \ - (WORD)ctrl.cmd[1] & 1, (WORD)ctrl.cmd[1]); - LOGWARN(" Reserved: %02X\n", (WORD)ctrl.cmd[2]); - LOGWARN(" Reserved: %02X\n", (WORD)ctrl.cmd[3]); - LOGWARN(" Parameter List Len %02X\n", (WORD)ctrl.cmd[4]); - LOGWARN(" Reserved: %02X\n",(WORD)ctrl.cmd[5]); - LOGWARN(" Ctrl Len: %08X\n",(WORD)ctrl.length); + Log(Log::Warning, "Received \'Mode Select\'\n"); + Log(Log::Warning, " Operation Code: [%02X]\n", ctrl.cmd[0]); + Log(Log::Warning, " Logical Unit %01X, PF %01X, SP %01X [%02X]\n", ctrl.cmd[1] >> 5, 1 & (ctrl.cmd[1] >> 4), ctrl.cmd[1] & 1, ctrl.cmd[1]); + Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[2]); + Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[3]); + Log(Log::Warning, " Parameter List Len %02X\n", ctrl.cmd[4]); + Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[5]); + Log(Log::Warning, " Ctrl Len: %08X\n",ctrl.length); if (!ctrl.unit[lun]->ModeSelect( ctrl.cmd, ctrl.buffer, ctrl.offset)) { // MODE SELECT failed - LOGWARN("Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]); + Log(Log::Warning, "Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]); return; } break; - case SCSIDEV::eCmdSetIfaceMode: - LOGWARN("%s Trying to flush a command set interface mode. This should be a daynaport?", __PRETTY_FUNCTION__); - break; - case SCSIDEV::eCmdSetMcastAddr: - // TODO: Eventually, we should store off the multicast address configuration data here... - break; + default: - LOGWARN("Received an unexpected flush command %02X!!!!!\n",(WORD)ctrl.cmd[0]); - // The following statement makes debugging a huge pain. You can un-comment it - // if you're not trying to add new devices.... - // ASSERT(FALSE); + Log(Log::Warning, "Received an invalid flush command %02X!!!!!\n",ctrl.cmd[0]); + ASSERT(FALSE); break; } } @@ -1932,3 +1929,71 @@ void SASIDEV::GetPhaseStr(char *str) } } #endif + +//--------------------------------------------------------------------------- +// +// Log output +// +// TODO: This function needs some cleanup. Its very kludgey +//--------------------------------------------------------------------------- +void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...) +{ +#if !defined(BAREMETAL) +#ifdef DISK_LOG + char buffer[0x200]; + char buffer2[0x250]; + char buffer3[0x250]; + char phase_str[20]; +#endif + va_list args; + va_start(args, format); + + if(this->GetID() != 6) + { + return; + } + +#ifdef RASCSI +#ifndef DISK_LOG + if (level == Log::Warning) { + return; + } +#endif // DISK_LOG +#endif // RASCSI + +#ifdef DISK_LOG + // format + vsprintf(buffer, format, args); + + // end variable length argument + va_end(args); + + // Add the date/timestamp + // current date/time based on current system + time_t now = time(0); + // convert now to string form + char* dt = ctime(&now); + + + strcpy(buffer2, "["); + strcat(buffer2, dt); + // Get rid of the carriage return + buffer2[strlen(buffer2)-1] = '\0'; + strcat(buffer2, "] "); + + // Get the phase + this->GetPhaseStr(phase_str); + sprintf(buffer3, "[%d][%s] ", this->GetID(), phase_str); + strcat(buffer2,buffer3); + strcat(buffer2, buffer); + + + // Log output +#ifdef RASCSI + printf("%s\n", buffer2); +#else + host->GetVM()->GetLog()->Format(level, host, buffer); +#endif // RASCSI +#endif // BAREMETAL +#endif // DISK_LOG +} diff --git a/src/raspberrypi/controllers/sasidev_ctrl.h b/src/raspberrypi/controllers/sasidev_ctrl.h index 7f7bfb3f..fc8ec2d0 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.h +++ b/src/raspberrypi/controllers/sasidev_ctrl.h @@ -46,9 +46,9 @@ public: // Internal data definition typedef struct { - // General + // 全般 BUS::phase_t phase; // Transition phase - int m_scsi_id; // Controller ID (0-7) + int id; // Controller ID (0-7) BUS *bus; // Bus // commands @@ -116,7 +116,7 @@ public: void FASTCALL GetPhaseStr(char *str); #endif - int FASTCALL GetSCSIID() {return ctrl.m_scsi_id;} + int FASTCALL GetID() {return ctrl.id;} // Get the ID void FASTCALL GetCTRL(ctrl_t *buffer); // Get the internal information @@ -161,9 +161,9 @@ protected: // FORMAT command void FASTCALL CmdReassign(); // REASSIGN BLOCKS command - virtual void FASTCALL CmdRead6(); + void FASTCALL CmdRead6(); // READ(6) command - virtual void FASTCALL CmdWrite6(); + void FASTCALL CmdWrite6(); // WRITE(6) command void FASTCALL CmdSeek6(); // SEEK(6) command @@ -173,8 +173,6 @@ protected: // SPECIFY command void FASTCALL CmdInvalid(); // Unsupported command - void FASTCALL DaynaPortWrite(); - // DaynaPort specific 'write' operation // データ転送 virtual void FASTCALL Send(); @@ -198,6 +196,10 @@ protected: void FASTCALL FlushUnit(); // Flush the logical unit + // Log + void FASTCALL Log(Log::loglevel level, const char *format, ...); + // Log output + protected: #ifndef RASCSI Device *host; diff --git a/src/raspberrypi/controllers/scsidev_ctrl.cpp b/src/raspberrypi/controllers/scsidev_ctrl.cpp index da9b6b79..a496eeb4 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.cpp +++ b/src/raspberrypi/controllers/scsidev_ctrl.cpp @@ -13,11 +13,10 @@ // [ SCSI device controller ] // //--------------------------------------------------------------------------- -#include "log.h" #include "controllers/scsidev_ctrl.h" #include "gpiobus.h" #include "devices/scsi_host_bridge.h" -#include "devices/scsi_daynaport.h" +#include "rascsi_version.h" //=========================================================================== // @@ -73,16 +72,18 @@ BUS::phase_t FASTCALL SCSIDEV::Process() ASSERT(this); // Do nothing if not connected - if (ctrl.m_scsi_id < 0 || ctrl.bus == NULL) { + if (ctrl.id < 0 || ctrl.bus == NULL) { return ctrl.phase; } // Get bus information ((GPIOBUS*)ctrl.bus)->Aquire(); - // Check to see if the reset signal was asserted + // Reset if (ctrl.bus->GetRST()) { - LOGWARN("RESET signal received!"); +#if defined(DISK_LOG) + Log(Log::Normal, "RESET信号受信"); +#endif // DISK_LOG // Reset the controller Reset(); @@ -145,7 +146,7 @@ BUS::phase_t FASTCALL SCSIDEV::Process() //--------------------------------------------------------------------------- // -// Phases +// Phaes // //--------------------------------------------------------------------------- @@ -161,7 +162,9 @@ void FASTCALL SCSIDEV::BusFree() // Phase change if (ctrl.phase != BUS::busfree) { - LOGTRACE( "%s Bus free phase", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "Bus free phase"); +#endif // DISK_LOG // Phase setting ctrl.phase = BUS::busfree; @@ -202,7 +205,7 @@ void FASTCALL SCSIDEV::Selection() // Phase change if (ctrl.phase != BUS::selection) { // invalid if IDs do not match - id = 1 << ctrl.m_scsi_id; + id = 1 << ctrl.id; if ((ctrl.bus->GetDAT() & id) == 0) { return; } @@ -212,7 +215,10 @@ void FASTCALL SCSIDEV::Selection() return; } - LOGTRACE("%s Selection Phase ID=%d (with device)", __PRETTY_FUNCTION__, (int)ctrl.m_scsi_id); +#if defined(DISK_LOG) + Log(Log::Normal, + "Selection Phase ID=%d (with device)", ctrl.id); +#endif // DISK_LOG // Phase setting ctrl.phase = BUS::selection; @@ -242,7 +248,9 @@ void FASTCALL SCSIDEV::Execute() { ASSERT(this); - LOGTRACE( "%s Execution phase command $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[0]); +#if defined(DISK_LOG) + Log(Log::Normal, "Execution phase command $%02X", ctrl.cmd[0]); +#endif // DISK_LOG // Phase Setting ctrl.phase = BUS::execute; @@ -255,188 +263,157 @@ void FASTCALL SCSIDEV::Execute() #endif // RASCSI // Process by command - switch ((scsi_command)ctrl.cmd[0]) { + switch (ctrl.cmd[0]) { // TEST UNIT READY - case eCmdTestUnitReady: - LOGDEBUG("++++ CMD ++++ %s Received eCmdTestUnitReady", __PRETTY_FUNCTION__); + case 0x00: CmdTestUnitReady(); return; // REZERO - case eCmdRezero: + case 0x01: CmdRezero(); return; // REQUEST SENSE - case eCmdRequestSense: - LOGDEBUG("++++ CMD ++++ %s Received eCmdRequestSense", __PRETTY_FUNCTION__); + case 0x03: CmdRequestSense(); return; // FORMAT UNIT - case eCmdFormat: + case 0x04: CmdFormat(); return; // REASSIGN BLOCKS - case eCmdReassign: + case 0x07: CmdReassign(); return; // READ(6) - case eCmdRead6: - LOGTRACE("++++ CMD ++++ %s Received eCmdRead6", __PRETTY_FUNCTION__); + case 0x08: CmdRead6(); return; - case eCmdRetrieveStats: - LOGDEBUG("++++ CMD ++++ %s Received eCmdRetrieveStats", __PRETTY_FUNCTION__); - CmdRetrieveStats(); - return; - - case eCmdSetIfaceMode: - LOGDEBUG("++++ CMD ++++ %s Received eCmdSetIfaceMode", __PRETTY_FUNCTION__); - CmdSetIfaceMode(); - return; - - case eCmdSetMcastAddr: - LOGDEBUG("++++ CMD ++++ %s Received eCmdSetMcastAddr", __PRETTY_FUNCTION__); - CmdSetMcastAddr(); - return; - - case eCmdEnableInterface: - LOGDEBUG("++++ CMD ++++ %s Received eCmdEnableInterface", __PRETTY_FUNCTION__); - CmdEnableInterface(); - return; - // WRITE(6) - case eCmdWrite6: - LOGDEBUG("++++ CMD ++++ %s Received eCmdWrite6", __PRETTY_FUNCTION__); + case 0x0a: CmdWrite6(); return; // SEEK(6) - case eCmdSeek6: - LOGDEBUG("++++ CMD ++++ %s Received eCmdSeek6", __PRETTY_FUNCTION__); + case 0x0b: CmdSeek6(); return; // INQUIRY - case eCmdInquiry: - LOGDEBUG("++++ CMD ++++ %s Received eCmdInquiry", __PRETTY_FUNCTION__); + case 0x12: CmdInquiry(); return; // MODE SELECT - case eCmdModeSelect: - LOGDEBUG("++++ CMD ++++ %s Received eCmdModeSelect", __PRETTY_FUNCTION__); + case 0x15: CmdModeSelect(); return; - // MODE SENSE - case eCmdModeSense: - LOGDEBUG("++++ CMD ++++ %s Received eCmdModeSense", __PRETTY_FUNCTION__); + // MDOE SENSE + case 0x1a: CmdModeSense(); return; // START STOP UNIT - case eCmdStartStop: - LOGDEBUG("++++ CMD ++++ %s Received eCmdStartStop", __PRETTY_FUNCTION__); + case 0x1b: CmdStartStop(); return; // SEND DIAGNOSTIC - case eCmdSendDiag: - LOGDEBUG("++++ CMD ++++ %s Received eCmdSendDiag", __PRETTY_FUNCTION__); + case 0x1d: CmdSendDiag(); return; // PREVENT/ALLOW MEDIUM REMOVAL - case eCmdRemoval: + case 0x1e: CmdRemoval(); return; // READ CAPACITY - case eCmdReadCapacity: + case 0x25: CmdReadCapacity(); return; // READ(10) - case eCmdRead10: - LOGDEBUG("++++ CMD ++++ %s Received eCmdRead10", __PRETTY_FUNCTION__); + case 0x28: CmdRead10(); return; // WRITE(10) - // WRITE and VERIFY(10) - case eCmdWrite10: - case eCmdWriteAndVerify10: - LOGDEBUG("++++ CMD ++++ %s Received eCmdWrite10", __PRETTY_FUNCTION__); + case 0x2a: CmdWrite10(); return; // SEEK(10) - case eCmdSeek10: + case 0x2b: CmdSeek10(); return; + // WRITE and VERIFY + case 0x2e: + CmdWrite10(); + return; + // VERIFY - case eCmdVerify: + case 0x2f: CmdVerify(); return; // SYNCHRONIZE CACHE - case eCmdSynchronizeCache: + case 0x35: CmdSynchronizeCache(); return; // READ DEFECT DATA(10) - case eCmdReadDefectData10: + case 0x37: CmdReadDefectData10(); return; // READ TOC - case eCmdReadToc: + case 0x43: CmdReadToc(); return; // PLAY AUDIO(10) - case eCmdPlayAudio10: + case 0x45: CmdPlayAudio10(); return; // PLAY AUDIO MSF - case eCmdPlayAudioMSF: + case 0x47: CmdPlayAudioMSF(); return; // PLAY AUDIO TRACK - case eCmdPlayAudioTrack: + case 0x48: CmdPlayAudioTrack(); return; // MODE SELECT(10) - case eCmdModeSelect10: + case 0x55: CmdModeSelect10(); return; // MDOE SENSE(10) - case eCmdModeSense10: + case 0x5a: CmdModeSense10(); return; // SPECIFY (SASI only/Suppress warning when using SxSI) - case eCmdInvalid: + case 0xc2: CmdInvalid(); return; - default: - // No other support - LOGWARN("%s Received unsupported command: $%02X", __PRETTY_FUNCTION__, (BYTE)ctrl.cmd[0]); - CmdInvalid(); } - return; + // No other support + Log(Log::Normal, "Unsupported command received: $%02X", ctrl.cmd[0]); + CmdInvalid(); } //--------------------------------------------------------------------------- @@ -447,12 +424,13 @@ void FASTCALL SCSIDEV::Execute() void FASTCALL SCSIDEV::MsgOut() { ASSERT(this); - LOGTRACE("%s ID: %d",__PRETTY_FUNCTION__, this->GetSCSIID()); // Phase change if (ctrl.phase != BUS::msgout) { - LOGTRACE("Message Out Phase"); +#if defined(DISK_LOG) + Log(Log::Normal, "Message Out Phase"); +#endif // DISK_LOG // Message out phase after selection // process the IDENTIFY message @@ -482,8 +460,23 @@ void FASTCALL SCSIDEV::MsgOut() return; } +#ifdef RASCSI // Receive Receive(); +#else + // Requesting + if (ctrl.bus->GetREQ()) { + // Sent by the initiator + if (ctrl.bus->GetACK()) { + Receive(); + } + } else { + // Request the initator to + if (!ctrl.bus->GetACK()) { + ReceiveNext(); + } + } +#endif // RASCSI } //--------------------------------------------------------------------------- @@ -514,7 +507,9 @@ void FASTCALL SCSIDEV::Error() return; } - LOGTRACE( "%s Error (to status phase)", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "Error (to status phase)"); +#endif // DISK_LOG // Set status and message(CHECK CONDITION) ctrl.status = 0x02; @@ -544,7 +539,9 @@ void FASTCALL SCSIDEV::CmdInquiry() ASSERT(this); - LOGTRACE("%s INQUIRY Command", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "INQUIRY Command"); +#endif // DISK_LOG // Find a valid unit disk = NULL; @@ -557,9 +554,8 @@ void FASTCALL SCSIDEV::CmdInquiry() // Processed on the disk side (it is originally processed by the controller) if (disk) { - major = (DWORD)(RASCSI >> 8); - minor = (DWORD)(RASCSI & 0xff); - LOGTRACE("%s Buffer size is %d",__PRETTY_FUNCTION__, ctrl.bufsize); + major = (DWORD)rascsi_major_version; + minor = (DWORD)rascsi_minor_version; ctrl.length = ctrl.unit[lun]->Inquiry(ctrl.cmd, ctrl.buffer, major, minor); } else { @@ -592,7 +588,9 @@ void FASTCALL SCSIDEV::CmdModeSelect() ASSERT(this); - LOGTRACE( "%s MODE SELECT Command", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "MODE SELECT Command"); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -624,7 +622,9 @@ void FASTCALL SCSIDEV::CmdModeSense() ASSERT(this); - LOGTRACE( "%s MODE SENSE Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "MODE SENSE Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -637,7 +637,8 @@ void FASTCALL SCSIDEV::CmdModeSense() ctrl.length = ctrl.unit[lun]->ModeSense(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length >= 0); if (ctrl.length == 0) { - LOGWARN("%s Not supported MODE SENSE page $%02X",__PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[2]); + Log(Log::Warning, + "Not supported MODE SENSE page $%02X", ctrl.cmd[2]); // Failure (Error) Error(); @@ -660,7 +661,9 @@ void FASTCALL SCSIDEV::CmdStartStop() ASSERT(this); - LOGTRACE( "%s START STOP UNIT Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "START STOP UNIT Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -693,7 +696,9 @@ void FASTCALL SCSIDEV::CmdSendDiag() ASSERT(this); - LOGTRACE( "%s SEND DIAGNOSTIC Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "SEND DIAGNOSTIC Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -726,7 +731,9 @@ void FASTCALL SCSIDEV::CmdRemoval() ASSERT(this); - LOGTRACE( "%s PREVENT/ALLOW MEDIUM REMOVAL Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "PREVENT/ALLOW MEDIUM REMOVAL Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -759,7 +766,9 @@ void FASTCALL SCSIDEV::CmdReadCapacity() ASSERT(this); - LOGTRACE( "%s READ CAPACITY Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "READ CAPACITY Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -820,7 +829,9 @@ void FASTCALL SCSIDEV::CmdRead10() ctrl.blocks <<= 8; ctrl.blocks |= ctrl.cmd[8]; - LOGTRACE("%s READ(10) command record=%08X block=%d", __PRETTY_FUNCTION__, (unsigned int)record, (int)ctrl.blocks); +#if defined(DISK_LOG) + Log(Log::Normal, "READ(10) command record=%08X block=%d", record, ctrl.blocks); +#endif // DISK_LOG // Do not process 0 blocks if (ctrl.blocks == 0) { @@ -829,7 +840,7 @@ void FASTCALL SCSIDEV::CmdRead10() } // Command processing on drive - ctrl.length = ctrl.unit[lun]->Read(ctrl.cmd, ctrl.buffer, record); + ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record); if (ctrl.length <= 0) { // Failure (Error) Error(); @@ -880,7 +891,10 @@ void FASTCALL SCSIDEV::CmdWrite10() ctrl.blocks <<= 8; ctrl.blocks |= ctrl.cmd[8]; - LOGTRACE("%s WRTIE(10) command record=%08X blocks=%d",__PRETTY_FUNCTION__, (unsigned int)record, (unsigned int)ctrl.blocks); +#if defined(DISK_LOG) + Log(Log::Normal, + "WRTIE(10) command record=%08X blocks=%d", record, ctrl.blocks); +#endif // DISK_LOG // Do not process 0 blocks if (ctrl.blocks == 0) { @@ -915,7 +929,9 @@ void FASTCALL SCSIDEV::CmdSeek10() ASSERT(this); - LOGTRACE( "%s SEEK(10) Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "SEEK(10) Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -968,7 +984,10 @@ void FASTCALL SCSIDEV::CmdVerify() ctrl.blocks <<= 8; ctrl.blocks |= ctrl.cmd[8]; - LOGTRACE("%s VERIFY command record=%08X blocks=%d",__PRETTY_FUNCTION__, (unsigned int)record, (int)ctrl.blocks); +#if defined(DISK_LOG) + Log(Log::Normal, + "VERIFY command record=%08X blocks=%d", record, ctrl.blocks); +#endif // DISK_LOG // Do not process 0 blocks if (ctrl.blocks == 0) { @@ -992,7 +1011,7 @@ void FASTCALL SCSIDEV::CmdVerify() } // Test loading - ctrl.length = ctrl.unit[lun]->Read(ctrl.cmd, ctrl.buffer, record); + ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record); if (ctrl.length <= 0) { // Failure (Error) Error(); @@ -1041,7 +1060,9 @@ void FASTCALL SCSIDEV::CmdReadDefectData10() ASSERT(this); - LOGTRACE( "%s READ DEFECT DATA(10) Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "READ DEFECT DATA(10) Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1197,7 +1218,9 @@ void FASTCALL SCSIDEV::CmdModeSelect10() ASSERT(this); - LOGTRACE( "%s MODE SELECT10 Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "MODE SELECT10 Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1229,7 +1252,9 @@ void FASTCALL SCSIDEV::CmdModeSense10() ASSERT(this); - LOGTRACE( "%s MODE SENSE(10) Command ", __PRETTY_FUNCTION__); +#if defined(DISK_LOG) + Log(Log::Normal, "MODE SENSE(10) Command "); +#endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1242,7 +1267,8 @@ void FASTCALL SCSIDEV::CmdModeSense10() ctrl.length = ctrl.unit[lun]->ModeSense10(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length >= 0); if (ctrl.length == 0) { - LOGWARN("%s Not supported MODE SENSE(10) page $%02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[2]); + Log(Log::Warning, + "Not supported MODE SENSE(10) page $%02X", ctrl.cmd[2]); // Failure (Error) Error(); @@ -1273,9 +1299,7 @@ void FASTCALL SCSIDEV::CmdGetMessage10() } // 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'))){ - LOGWARN("Received a GetMessage10 command for a non-bridge unit"); + if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) { Error(); return; } @@ -1309,8 +1333,6 @@ void FASTCALL SCSIDEV::CmdGetMessage10() // // SEND MESSAGE(10) // -// This Send Message command is used by the X68000 host driver -// //--------------------------------------------------------------------------- void FASTCALL SCSIDEV::CmdSendMessage10() { @@ -1327,7 +1349,6 @@ void FASTCALL SCSIDEV::CmdSendMessage10() // Error if not a host bridge if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) { - LOGERROR("Received CmdSendMessage10 for a non-bridge device"); Error(); return; } @@ -1360,186 +1381,6 @@ void FASTCALL SCSIDEV::CmdSendMessage10() DataOut(); } -//--------------------------------------------------------------------------- -// -// Retrieve Statistics (09) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIDEV::CmdRetrieveStats() -{ - DWORD lun; - SCSIDaynaPort *dayna_port; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // 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()); - Error(); - return; - } - - // Process with drive - dayna_port = (SCSIDaynaPort*)ctrl.unit[lun]; - ctrl.length = dayna_port->RetrieveStats(ctrl.cmd, ctrl.buffer); - - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Set next block - ctrl.blocks = 1; - ctrl.next = 1; - - // Data in phase - DataIn(); -} - -//--------------------------------------------------------------------------- -// -// Set Interface Mode (0c) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIDEV::CmdSetIfaceMode() -{ - DWORD lun; - // BOOL status; - SCSIDaynaPort *dayna_port; - - ASSERT(this); - - LOGTRACE("%s",__PRETTY_FUNCTION__); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // 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()); - Error(); - return; - } - - dayna_port = (SCSIDaynaPort*)ctrl.unit[lun]; - - // Check whether this command is telling us to "Set Interface Mode" - // or "Set MAC Address" - - ctrl.length = dayna_port->RetrieveStats(ctrl.cmd, ctrl.buffer); - switch(ctrl.cmd[5]){ - case SCSIDaynaPort::CMD_SCSILINK_SETMODE: - dayna_port->SetMode(ctrl.cmd, ctrl.buffer); - Status(); - break; - break; - case SCSIDaynaPort::CMD_SCSILINK_SETMAC: - ctrl.length = 6; - // Write phase - DataOut(); - break; - default: - LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, (unsigned int)ctrl.cmd[5]); - } -} - -//--------------------------------------------------------------------------- -// -// Set the multicast address -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIDEV::CmdSetMcastAddr() -{ - DWORD lun; - - ASSERT(this); - - LOGTRACE("%s Set Multicast Address Command ", __PRETTY_FUNCTION__); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'D', 'P')){ - LOGWARN("Received a SetMcastAddress command for a non-daynaport unit"); - Error(); - return; - } - - // Command processing on drive - ctrl.length = (DWORD)ctrl.cmd[4]; - - // ASSERT(ctrl.length >= 0); - if (ctrl.length == 0) { - LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, (WORD)ctrl.cmd[2]); - - // Failure (Error) - Error(); - return; - } - - DataOut(); -} - -//--------------------------------------------------------------------------- -// -// Enable/disable Interface (0e) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIDEV::CmdEnableInterface() -{ - DWORD lun=0; - BOOL status; - SCSIDaynaPort *dayna_port; - - ASSERT(this); - - LOGTRACE("%s",__PRETTY_FUNCTION__); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // 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()); - Error(); - return; - } - - dayna_port = (SCSIDaynaPort*)ctrl.unit[lun]; - - // Command processing on drive - status = dayna_port->EnableInterface(ctrl.cmd); - if (!status) { - // Failure (Error) - Error(); - return; - } - - // status phase - Status(); -} - - //=========================================================================== // // Data Transfer @@ -1565,7 +1406,6 @@ void FASTCALL SCSIDEV::Send() #ifdef RASCSI //if Length! = 0, send if (ctrl.length != 0) { - LOGTRACE("%s sending handhake with offset %lu, length %lu", __PRETTY_FUNCTION__, ctrl.offset, ctrl.length); len = ctrl.bus->SendHandShake( &ctrl.buffer[ctrl.offset], ctrl.length); @@ -1604,7 +1444,6 @@ void FASTCALL SCSIDEV::Send() if (ctrl.blocks != 0) { // // set next buffer (set offset, length) result = XferIn(ctrl.buffer); - LOGTRACE("%s processing after data collection. Blocks: %lu", __PRETTY_FUNCTION__, ctrl.blocks); #ifndef RASCSI ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); #endif // RASCSI @@ -1619,7 +1458,6 @@ void FASTCALL SCSIDEV::Send() // Continue sending if block !=0 if (ctrl.blocks != 0){ - LOGTRACE("%s Continuing to send. blocks = %lu", __PRETTY_FUNCTION__, ctrl.blocks); ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); #ifndef RASCSI @@ -1630,7 +1468,6 @@ void FASTCALL SCSIDEV::Send() } // Move to next phase - LOGTRACE("%s Move to next phase %s (%d)", __PRETTY_FUNCTION__, BUS::GetPhaseStrRaw(ctrl.phase), ctrl.phase); switch (ctrl.phase) { // Message in phase case BUS::msgin: @@ -1693,52 +1530,132 @@ void FASTCALL SCSIDEV::SendNext() } #endif // RASCSI +#ifndef RASCSI +//--------------------------------------------------------------------------- +// +// Receive data +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::Receive() +{ + DWORD data; + + ASSERT(this); + + // Req is up + ASSERT(ctrl.bus->GetREQ()); + ASSERT(!ctrl.bus->GetIO()); + + // Get data + data = (DWORD)ctrl.bus->GetDAT(); + + // Signal line operated by the target + ctrl.bus->SetREQ(FALSE); + + switch (ctrl.phase) { + // Command phase + case BUS::command: + ctrl.cmd[ctrl.offset] = data; +#if defined(DISK_LOG) + Log(Log::Normal, "Command phase $%02X", data); +#endif // DISK_LOG + + // Set the length again with the first data (offset 0) + if (ctrl.offset == 0) { + if (ctrl.cmd[0] >= 0x20) { + // 10バイトCDB + ctrl.length = 10; + } + } + break; + + // Message out phase + case BUS::msgout: + ctrl.message = data; +#if defined(DISK_LOG) + Log(Log::Normal, "Message out phase $%02X", data); +#endif // DISK_LOG + break; + + // Data out phase + case BUS::dataout: + ctrl.buffer[ctrl.offset] = (BYTE)data; + break; + + // Other (impossible) + default: + ASSERT(FALSE); + break; + } +} +#endif // RASCSI + +#ifdef RASCSI //--------------------------------------------------------------------------- // // Receive Data // //--------------------------------------------------------------------------- void FASTCALL SCSIDEV::Receive() +#else +//--------------------------------------------------------------------------- +// +// Continue receiving data +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::ReceiveNext() +#endif // RASCSI { +#ifdef RASCSI int len; +#endif // RASCSI BOOL result; int i; BYTE data; ASSERT(this); - LOGTRACE("%s",__PRETTY_FUNCTION__); - // REQ is low ASSERT(!ctrl.bus->GetREQ()); ASSERT(!ctrl.bus->GetIO()); +#ifdef RASCSI // Length != 0 if received if (ctrl.length != 0) { - LOGTRACE("%s length was != 0", __PRETTY_FUNCTION__); // Receive len = ctrl.bus->ReceiveHandShake( &ctrl.buffer[ctrl.offset], ctrl.length); // If not able to receive all, move to status phase if (len != (int)ctrl.length) { - LOGERROR("%s Not able to receive all data. Going to error",__PRETTY_FUNCTION__); Error(); return; } // Offset and Length ctrl.offset += ctrl.length; - ctrl.length = 0; + ctrl.length = 0;; return; } +#else + // Offset and Length + ASSERT(ctrl.length >= 1); + ctrl.offset++; + ctrl.length--; + + // If length!=0, set req again + if (ctrl.length != 0) { + // Signal line operated by the target + ctrl.bus->SetREQ(TRUE); + return; + } +#endif // RASCSI // Block subtraction, result initialization ctrl.blocks--; result = TRUE; // Processing after receiving data (by phase) - LOGTRACE("%s ctrl.phase: %d (%s)",__PRETTY_FUNCTION__, (int)ctrl.phase, BUS::GetPhaseStrRaw(ctrl.phase)); switch (ctrl.phase) { // Data out phase @@ -1779,6 +1696,10 @@ void FASTCALL SCSIDEV::Receive() if (ctrl.blocks != 0){ ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); +#ifndef RASCSI + // Signal line operated by the target + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } @@ -1786,6 +1707,7 @@ void FASTCALL SCSIDEV::Receive() switch (ctrl.phase) { // Command phase case BUS::command: +#ifdef RASCSI // Command data transfer len = 6; if (ctrl.buffer[0] >= 0x20 && ctrl.buffer[0] <= 0x7D) { @@ -1794,8 +1716,11 @@ void FASTCALL SCSIDEV::Receive() } for (i = 0; i < len; i++) { ctrl.cmd[i] = (DWORD)ctrl.buffer[i]; - LOGTRACE("%s Command $%02X",__PRETTY_FUNCTION__, (int)ctrl.cmd[i]); +#if defined(DISK_LOG) + Log(Log::Normal, "Command $%02X", ctrl.cmd[i]); +#endif // DISK_LOG } +#endif // RASCSI // Execution Phase Execute(); @@ -1809,7 +1734,10 @@ void FASTCALL SCSIDEV::Receive() ctrl.offset = 0; ctrl.length = 1; ctrl.blocks = 1; - +#ifndef RASCSI + // Request message + ctrl.bus->SetREQ(TRUE); +#endif // RASCSI return; } @@ -1822,14 +1750,20 @@ void FASTCALL SCSIDEV::Receive() // ABORT if (data == 0x06) { - LOGTRACE("Message code ABORT $%02X", (int)data); +#if defined(DISK_LOG) + Log(Log::Normal, + "Message code ABORT $%02X", data); +#endif // DISK_LOG BusFree(); return; } // BUS DEVICE RESET if (data == 0x0C) { - LOGTRACE("Message code BUS DEVICE RESET $%02X", (int)data); +#if defined(DISK_LOG) + Log(Log::Normal, + "Message code BUS DEVICE RESET $%02X", data); +#endif // DISK_LOG scsi.syncoffset = 0; BusFree(); return; @@ -1837,12 +1771,18 @@ void FASTCALL SCSIDEV::Receive() // IDENTIFY if (data >= 0x80) { - LOGTRACE("Message code IDENTIFY $%02X", (int)data); +#if defined(DISK_LOG) + Log(Log::Normal, + "Message code IDENTIFY $%02X", data); +#endif // DISK_LOG } // Extended Message if (data == 0x01) { - LOGTRACE("Message code EXTENDED MESSAGE $%02X", (int)data); +#if defined(DISK_LOG) + Log(Log::Normal, + "Message code EXTENDED MESSAGE $%02X", data); +#endif // DISK_LOG // Check only when synchronous transfer is possible if (!scsi.syncenable || scsi.msb[i + 2] != 0x01) { diff --git a/src/raspberrypi/controllers/scsidev_ctrl.h b/src/raspberrypi/controllers/scsidev_ctrl.h index c5318efd..f830b2d0 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.h +++ b/src/raspberrypi/controllers/scsidev_ctrl.h @@ -38,74 +38,13 @@ public: BYTE msb[256]; } scsi_t; - - enum scsi_message_code : BYTE { - eMsgCodeAbort = 0x06, - eMsgCodeAbortTag = 0x0D, - eMsgCodeBusDeviceReset = 0x0C, - eMsgCodeClearQueue = 0x0E, - eMsgCodeCommandComplete = 0x00, - eMsgCodeDisconnect = 0x04, - eMsgCodeIdentify = 0x80, - eMsgCodeIgnoreWideResidue = 0x23, // (Two Bytes) - eMsgCodeInitiateRecovery = 0x0F, - eMsgCodeInitiatorDetectedError = 0x05, - eMsgCodeLinkedCommandComplete = 0x0A, - eMsgCodeLinkedCommandCompleteWithFlag = 0x0B, - eMsgCodeMessageParityError = 0x09, - eMsgCodeMessageReject = 0x07, - eMsgCodeNoOperation = 0x08, - eMsgCodeHeadOfQueueTag = 0x21, - eMsgCodeOrderedQueueTag = 0x22, - eMsgCodeSimpleQueueTag = 0x20, - eMsgCodeReleaseRecovery = 0x10, - eMsgCodeRestorePointers = 0x03, - eMsgCodeSaveDataPointer = 0x02, - eMsgCodeTerminateIOProcess = 0x11, - }; - - - enum scsi_command : BYTE { - eCmdTestUnitReady = 0x00, - eCmdRezero = 0x01, - eCmdRequestSense = 0x03, - eCmdFormat = 0x04, - eCmdReassign = 0x07, - eCmdRead6 = 0x08, - eCmdRetrieveStats = 0x09, // DaynaPort specific command - eCmdWrite6 = 0x0A, - eCmdSeek6 = 0x0B, - eCmdSetIfaceMode = 0x0C, // DaynaPort specific command - eCmdSetMcastAddr = 0x0D, // DaynaPort specific command - eCmdEnableInterface = 0x0E, // DaynaPort specific command - eCmdInquiry = 0x12, - eCmdModeSelect = 0x15, - eCmdModeSense = 0x1A, - eCmdStartStop = 0x1B, - eCmdRcvDiag = 0x1C, - eCmdSendDiag = 0x1D, - eCmdRemoval = 0x1E, - eCmdReadCapacity = 0x25, - eCmdRead10 = 0x28, - eCmdWrite10 = 0x2A, - eCmdSeek10 = 0x2B, - eCmdWriteAndVerify10 = 0x2E, - eCmdVerify = 0x2F, - eCmdSynchronizeCache = 0x35, - eCmdReadDefectData10 = 0x37, - eCmdReadToc = 0x43, - eCmdPlayAudio10 = 0x45, - eCmdPlayAudioMSF = 0x47, - eCmdPlayAudioTrack = 0x48, - eCmdModeSelect10 = 0x55, - eCmdModeSense10 = 0x5A, - eCmdInvalid = 0xC2, // (SASI only/Suppress warning when using SxSI) - eCmdSasiCmdAssign = 0x0e, // This isn't used by SCSI, and can probably be removed. - }; - public: // Basic Functions +#ifdef RASCSI SCSIDEV(); +#else + SCSIDEV(Device *dev); +#endif // RASCSI // Constructor void FASTCALL Reset(); @@ -180,16 +119,8 @@ private: // GET MESSAGE(10) command void FASTCALL CmdSendMessage10(); // SEND MESSAGE(10) command - void FASTCALL CmdRetrieveStats(); - // DaynaPort specific command - void FASTCALL CmdSetIfaceMode(); - // DaynaPort specific command - void FASTCALL CmdSetMcastAddr(); - // DaynaPort specific command - void FASTCALL CmdEnableInterface(); - // DaynaPort specific command - // Data transfer + // データ転送 void FASTCALL Send(); // Send data #ifndef RASCSI diff --git a/src/raspberrypi/devices/ctapdriver.cpp b/src/raspberrypi/devices/ctapdriver.cpp index 098c20df..e06e3eb0 100644 --- a/src/raspberrypi/devices/ctapdriver.cpp +++ b/src/raspberrypi/devices/ctapdriver.cpp @@ -5,19 +5,16 @@ // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS -// Copyright (C) akuker // -// Imported NetBSD support and some optimisation patches by Rin Okuyama. +// Imported NetBSD support and some optimisation patch by Rin Okuyama. // // [ TAP Driver ] // //--------------------------------------------------------------------------- -#include // For crc32() #include "os.h" #include "xm6.h" #include "ctapdriver.h" -#include "log.h" //--------------------------------------------------------------------------- // @@ -26,7 +23,6 @@ //--------------------------------------------------------------------------- CTapDriver::CTapDriver() { - LOGTRACE("%s",__PRETTY_FUNCTION__); // Initialization m_hTAP = -1; memset(&m_MacAddr, 0, sizeof(m_MacAddr)); @@ -40,56 +36,38 @@ CTapDriver::CTapDriver() #ifdef __linux__ BOOL FASTCALL CTapDriver::Init() { - LOGTRACE("%s",__PRETTY_FUNCTION__); - char dev[IFNAMSIZ] = "ras0"; struct ifreq ifr; int ret; ASSERT(this); - LOGTRACE("Opening Tap device"); // TAP device initilization if ((m_hTAP = open("/dev/net/tun", O_RDWR)) < 0) { - LOGERROR("Error: can't open tun. Errno: %d %s", errno, strerror(errno)); + printf("Error: can't open tun\n"); return FALSE; } - LOGTRACE("Opened tap device %d",m_hTAP); - // IFF_NO_PI for no extra packet information memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy(ifr.ifr_name, dev, IFNAMSIZ); - LOGTRACE("Going to open %s", ifr.ifr_name); if ((ret = ioctl(m_hTAP, TUNSETIFF, (void *)&ifr)) < 0) { - LOGERROR("Error: can't ioctl TUNSETIFF. Errno: %d %s", errno, strerror(errno)); + printf("Error: can't ioctl TUNSETIFF\n"); close(m_hTAP); return FALSE; } - LOGTRACE("return code from ioctl was %d", ret); - LOGDEBUG("ip link set ras0 up"); - ret = run_system_cmd("ip link set ras0 up"); - LOGTRACE("return code from ip link set ras0 up was %d", ret); - - LOGDEBUG("brctl addif rascsi_bridge ras0"); - ret = run_system_cmd("brctl addif rascsi_bridge ras0"); - LOGTRACE("return code from brctl addif rascsi_bridge ras0 was %d", ret); - // Get MAC address - LOGTRACE("Getting the MAC address"); ifr.ifr_addr.sa_family = AF_INET; if ((ret = ioctl(m_hTAP, SIOCGIFHWADDR, &ifr)) < 0) { - LOGERROR("Error: can't ioctl SIOCGIFHWADDR. Errno: %d %s", errno, strerror(errno)); + printf("Error: can't ioctl SIOCGIFHWADDR\n"); close(m_hTAP); return FALSE; } - LOGTRACE("got the mac"); // Save MAC address memcpy(m_MacAddr, ifr.ifr_hwaddr.sa_data, sizeof(m_MacAddr)); - LOGINFO("Tap device %s created", ifr.ifr_name); return TRUE; } #endif // __linux__ @@ -104,20 +82,20 @@ BOOL FASTCALL CTapDriver::Init() // TAP Device Initialization if ((m_hTAP = open("/dev/tap", O_RDWR)) < 0) { - LOGERROR("Error: can't open tap. Errno: %d %s", errno, strerror(errno)); + printf("Error: can't open tap\n"); return FALSE; } // Get device name if (ioctl(m_hTAP, TAPGIFNAME, (void *)&ifr) < 0) { - LOGERROR("Error: can't ioctl TAPGIFNAME. Errno: %d %s", errno, strerror(errno)); + printf("Error: can't ioctl TAPGIFNAME\n"); close(m_hTAP); return FALSE; } // Get MAC address if (getifaddrs(&ifa) == -1) { - LOGERROR("Error: can't getifaddrs. Errno: %d %s", errno, strerror(errno)); + printf("Error: can't getifaddrs\n"); close(m_hTAP); return FALSE; } @@ -126,7 +104,7 @@ BOOL FASTCALL CTapDriver::Init() a->ifa_addr->sa_family == AF_LINK) break; if (a == NULL) { - LOGERROR("Error: can't get MAC addressErrno: %d %s", errno, strerror(errno)); + printf("Error: can't get MAC address\n"); close(m_hTAP); return FALSE; } @@ -136,7 +114,7 @@ BOOL FASTCALL CTapDriver::Init() sizeof(m_MacAddr)); freeifaddrs(ifa); - LOGINFO("Tap device : %s\n", ifr.ifr_name); + printf("Tap device : %s\n", ifr.ifr_name); return TRUE; } @@ -150,59 +128,14 @@ BOOL FASTCALL CTapDriver::Init() void FASTCALL CTapDriver::Cleanup() { ASSERT(this); - int result; - LOGDEBUG("brctl delif rascsi_bridge ras0"); - result = run_system_cmd("brctl delif rascsi_bridge ras0"); - if(result != EXIT_SUCCESS){ - LOGWARN("Warning: The brctl delif command failed."); - LOGWARN("You may need to manually remove the ras0 tap device from the bridge"); - } - - // Release TAP defice + // TAPデバイス解放 if (m_hTAP != -1) { close(m_hTAP); m_hTAP = -1; } } -//--------------------------------------------------------------------------- -// -// Enable -// -//--------------------------------------------------------------------------- -BOOL FASTCALL CTapDriver::Enable(){ - int result; - LOGDEBUG("%s: ip link set ras0 up", __PRETTY_FUNCTION__); - result = run_system_cmd("ip link set ras0 up"); - return (result == EXIT_SUCCESS); -} - -//--------------------------------------------------------------------------- -// -// Disable -// -//--------------------------------------------------------------------------- -BOOL FASTCALL CTapDriver::Disable(){ - int result; - LOGDEBUG("%s: ip link set ras0 down", __PRETTY_FUNCTION__); - result = run_system_cmd("ip link set ras0 down"); - return (result == EXIT_SUCCESS); -} - -//--------------------------------------------------------------------------- -// -// Flush -// -//--------------------------------------------------------------------------- -BOOL FASTCALL CTapDriver::Flush(){ - LOGTRACE("%s", __PRETTY_FUNCTION__); - while(PendingPackets()){ - (void)Rx(m_garbage_buffer); - } - return TRUE; -} - //--------------------------------------------------------------------------- // // MGet MAC Address @@ -221,9 +154,10 @@ void FASTCALL CTapDriver::GetMacAddr(BYTE *mac) // Receive // //--------------------------------------------------------------------------- -BOOL FASTCALL CTapDriver::PendingPackets() +int FASTCALL CTapDriver::Rx(BYTE *buf) { struct pollfd fds; + DWORD dwReceived; ASSERT(this); ASSERT(m_hTAP != -1); @@ -233,29 +167,7 @@ BOOL FASTCALL CTapDriver::PendingPackets() fds.events = POLLIN | POLLERR; fds.revents = 0; poll(&fds, 1, 0); - LOGTRACE("%s %u revents", __PRETTY_FUNCTION__, fds.revents); if (!(fds.revents & POLLIN)) { - return FALSE; - }else { - return TRUE; - } -} - -//--------------------------------------------------------------------------- -// -// Receive -// -//--------------------------------------------------------------------------- -int FASTCALL CTapDriver::Rx(BYTE *buf) -{ - DWORD dwReceived; - DWORD crc; - - ASSERT(this); - ASSERT(m_hTAP != -1); - - // Check if there is data that can be received - if(!PendingPackets()){ return 0; } @@ -267,23 +179,14 @@ int FASTCALL CTapDriver::Rx(BYTE *buf) // If reception is enabled if (dwReceived > 0) { - // We need to add the Frame Check Status (FCS) CRC back onto the end of the packet. - // The Linux network subsystem removes it, since most software apps shouldn't ever - // need it. + // Pad to the maximum frame size (60 bytes) excluding FCS + if (dwReceived < 60) { + memset(buf + dwReceived, 0, 60 - dwReceived); + dwReceived = 60; + } - // Initialize the CRC - crc = crc32(0L, Z_NULL, 0); - // Calculate the CRC - crc = crc32(crc, buf, dwReceived); - - buf[dwReceived + 0] = (BYTE)((crc >> 0) & 0xFF); - buf[dwReceived + 1] = (BYTE)((crc >> 8) & 0xFF); - buf[dwReceived + 2] = (BYTE)((crc >> 16) & 0xFF); - buf[dwReceived + 3] = (BYTE)((crc >> 24) & 0xFF); - - LOGDEBUG("%s CRC is %08lX - %02X %02X %02X %02X\n", __PRETTY_FUNCTION__, crc, buf[dwReceived+0], buf[dwReceived+1], buf[dwReceived+2], buf[dwReceived+3]); - - // Add FCS size to the received message size + // Add a dummy FCS + memset(buf + dwReceived, 0, 4); dwReceived += 4; } @@ -296,7 +199,7 @@ int FASTCALL CTapDriver::Rx(BYTE *buf) // Send // //--------------------------------------------------------------------------- -int FASTCALL CTapDriver::Tx(const BYTE *buf, int len) +int FASTCALL CTapDriver::Tx(BYTE *buf, int len) { ASSERT(this); ASSERT(m_hTAP != -1); diff --git a/src/raspberrypi/devices/ctapdriver.h b/src/raspberrypi/devices/ctapdriver.h index 02fb5695..68dffe66 100644 --- a/src/raspberrypi/devices/ctapdriver.h +++ b/src/raspberrypi/devices/ctapdriver.h @@ -5,7 +5,6 @@ // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS -// Copyright (C) akuker // // Imported NetBSD support and some optimisation patch by Rin Okuyama. // @@ -39,16 +38,8 @@ public: // Get Mac Address int FASTCALL Rx(BYTE *buf); // Receive - int FASTCALL Tx(const BYTE *buf, int len); + int FASTCALL Tx(BYTE *buf, int len); // Send - BOOL FASTCALL PendingPackets(); - // Check if there are IP packets available - BOOL FASTCALL Enable(); - // Enable the ras0 interface - BOOL FASTCALL Disable(); - // Disable the ras0 interface - BOOL FASTCALL Flush(); - // Purge all of the packets that are waiting to be processed private: BYTE m_MacAddr[6]; @@ -57,7 +48,6 @@ private: // Send Valid Flag int m_hTAP; // File handle - BYTE m_garbage_buffer[ETH_FRAME_LEN]; }; #endif // ctapdriver_h diff --git a/src/raspberrypi/devices/disk.cpp b/src/raspberrypi/devices/disk.cpp index 4701b2ff..a05f27ac 100644 --- a/src/raspberrypi/devices/disk.cpp +++ b/src/raspberrypi/devices/disk.cpp @@ -357,7 +357,6 @@ BOOL FASTCALL DiskTrack::Read(BYTE *buf, int sec) const ASSERT(buf); ASSERT((sec >= 0) & (sec < 0x100)); - LOGTRACE("%s reading sector: %d", __PRETTY_FUNCTION__,sec); // Error if not initialized if (!dt.init) { return FALSE; @@ -975,47 +974,6 @@ BOOL FASTCALL Disk::IsNULL() const return FALSE; } -//--------------------------------------------------------------------------- -// -// Retrieve the disk's ID -// -//--------------------------------------------------------------------------- -DWORD FASTCALL Disk::GetID() const -{ - return disk.id; -} - - -//--------------------------------------------------------------------------- -// -// Get cache writeback mode -// -//--------------------------------------------------------------------------- -BOOL FASTCALL Disk::IsCacheWB() -{ - return cache_wb; -} - -//--------------------------------------------------------------------------- -// -// Set cache writeback mode -// -//--------------------------------------------------------------------------- -void FASTCALL Disk::SetCacheWB(BOOL enable) -{ - cache_wb = enable; -} - -//--------------------------------------------------------------------------- -// -// Set unsupported command -// -//--------------------------------------------------------------------------- -void FASTCALL Disk::InvalidCmd() -{ - disk.code = DISK_INVALIDCMD; -} - //--------------------------------------------------------------------------- // // SASI Check @@ -1204,7 +1162,6 @@ BOOL FASTCALL Disk::CheckReady() if (disk.reset) { disk.code = DISK_DEVRESET; disk.reset = FALSE; - LOGTRACE("%s Disk in reset", __PRETTY_FUNCTION__); return FALSE; } @@ -1212,21 +1169,17 @@ BOOL FASTCALL Disk::CheckReady() if (disk.attn) { disk.code = DISK_ATTENTION; disk.attn = FALSE; - LOGTRACE("%s Disk in needs attention", __PRETTY_FUNCTION__); return FALSE; } // Return status if not ready if (!disk.ready) { disk.code = DISK_NOTREADY; - LOGTRACE("%s Disk not ready", __PRETTY_FUNCTION__); return FALSE; } // Initialization with no error disk.code = DISK_NOERROR; - LOGTRACE("%s Disk is ready!", __PRETTY_FUNCTION__); - return TRUE; } @@ -1269,7 +1222,6 @@ int FASTCALL Disk::RequestSense(const DWORD *cdb, BYTE *buf) // Size determination (according to allocation length) size = (int)cdb[4]; - LOGTRACE("%s size of data = %d", __PRETTY_FUNCTION__, size); ASSERT((size >= 0) && (size < 0x100)); // For SCSI-1, transfer 4 bytes when the size is 0 @@ -2014,7 +1966,7 @@ BOOL FASTCALL Disk::Reassign(const DWORD* /*cdb*/) // READ // //--------------------------------------------------------------------------- -int FASTCALL Disk::Read(const DWORD *cdb, BYTE *buf, DWORD block) +int FASTCALL Disk::Read(BYTE *buf, DWORD block) { ASSERT(this); ASSERT(buf); @@ -2074,12 +2026,11 @@ int FASTCALL Disk::WriteCheck(DWORD block) // WRITE // //--------------------------------------------------------------------------- -BOOL FASTCALL Disk::Write(const DWORD *cdb, const BYTE *buf, DWORD block) +BOOL FASTCALL Disk::Write(const BYTE *buf, DWORD block) { ASSERT(this); ASSERT(buf); - LOGTRACE("%s", __PRETTY_FUNCTION__); // Error if not ready if (!disk.ready) { disk.code = DISK_NOTREADY; diff --git a/src/raspberrypi/devices/disk.h b/src/raspberrypi/devices/disk.h index 5f8e9da3..725880fb 100644 --- a/src/raspberrypi/devices/disk.h +++ b/src/raspberrypi/devices/disk.h @@ -233,7 +233,7 @@ public: #endif // RASCSI // ID - DWORD FASTCALL GetID() const; + DWORD FASTCALL GetID() const { return disk.id; } // Get media ID BOOL FASTCALL IsNULL() const; // NULL check @@ -298,11 +298,11 @@ public: // FORMAT UNIT command BOOL FASTCALL Reassign(const DWORD *cdb); // REASSIGN UNIT command - virtual int FASTCALL Read(const DWORD *cdb, BYTE *buf, DWORD block); + virtual int FASTCALL Read(BYTE *buf, DWORD block); // READ command - virtual int FASTCALL WriteCheck(DWORD block); + int FASTCALL WriteCheck(DWORD block); // WRITE check - virtual BOOL FASTCALL Write(const DWORD *cdb, const BYTE *buf, DWORD block); + BOOL FASTCALL Write(const BYTE *buf, DWORD block); // WRITE command BOOL FASTCALL Seek(const DWORD *cdb); // SEEK command @@ -328,13 +328,13 @@ public: // PLAY AUDIO MSF command virtual BOOL FASTCALL PlayAudioTrack(const DWORD *cdb); // PLAY AUDIO TRACK command - void FASTCALL InvalidCmd(); + void FASTCALL InvalidCmd() { disk.code = DISK_INVALIDCMD; } // Unsupported command // Other - BOOL FASTCALL IsCacheWB(); + BOOL IsCacheWB() { return cache_wb; } // Get cache writeback mode - void FASTCALL SetCacheWB(BOOL enable); + void SetCacheWB(BOOL enable) { cache_wb = enable; } // Set cache writeback mode protected: diff --git a/src/raspberrypi/devices/scsi_daynaport.cpp b/src/raspberrypi/devices/scsi_daynaport.cpp deleted file mode 100644 index 4d6ce26d..00000000 --- a/src/raspberrypi/devices/scsi_daynaport.cpp +++ /dev/null @@ -1,540 +0,0 @@ -//--------------------------------------------------------------------------- -// -// SCSI Target Emulator RaSCSI (*^..^*) -// for Raspberry Pi -// -// Copyright (C) 2020 akuker -// Copyright (C) 2014-2020 GIMONS -// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) -// -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. -// -// [ Emulation of the DaynaPort SCSI Link Ethernet interface ] -// -// This design is derived from the SLINKCMD.TXT file, as well as David Kuder's -// Tiny SCSI Emulator -// - SLINKCMD: http://www.bitsavers.org/pdf/apple/scsi/dayna/daynaPORT/SLINKCMD.TXT -// - Tiny SCSI : https://hackaday.io/project/18974-tiny-scsi-emulator -// -// Additional documentation and clarification is available at the -// following link: -// - https://github.com/akuker/RASCSI/wiki/Dayna-Port-SCSI-Link -// -// This does NOT include the file system functionality that is present -// in the Sharp X68000 host bridge. -// -// Note: This requires the DaynaPort SCSI Link driver. -//--------------------------------------------------------------------------- - -#include "scsi_daynaport.h" - -//=========================================================================== -// -// DaynaPort SCSI Link Ethernet Adapter -// -//=========================================================================== -const char* SCSIDaynaPort::m_vendor_name = "DAYNA "; -const char* SCSIDaynaPort::m_device_name = "SCSI/Link "; -const char* SCSIDaynaPort::m_revision = "1.4a"; -const char* SCSIDaynaPort::m_firmware_version = "01.00.00"; - -const BYTE SCSIDaynaPort::m_bcast_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -const BYTE SCSIDaynaPort::m_apple_talk_addr[6] = { 0x09, 0x00, 0x07, 0xff, 0xff, 0xff }; - -//--------------------------------------------------------------------------- -// -// Constructor -// -//--------------------------------------------------------------------------- -SCSIDaynaPort::SCSIDaynaPort() : Disk() -{ - LOGTRACE("SCSI DaynaPort Constructor"); - // DaynaPort - disk.id = MAKEID('S', 'C', 'D', 'P'); - -#if defined(__linux__) && !defined(BAREMETAL) - // TAP Driver Generation - m_tap = new CTapDriver(); - m_bTapEnable = m_tap->Init(); - if(!m_bTapEnable){ - LOGERROR("Unable to open the TAP interface"); - }else { - LOGDEBUG("Tap interface created"); - } - - LOGTRACE("%s this->reset()", __PRETTY_FUNCTION__); - this->Reset(); - disk.ready = true; - disk.reset = false; - - // Generate MAC Address - LOGTRACE("%s memset(m_mac_addr, 0x00, 6);", __PRETTY_FUNCTION__); - memset(m_mac_addr, 0x00, 6); - - // if (m_bTapEnable) { - // tap->GetMacAddr(m_mac_addr); - // m_mac_addr[5]++; - // } - // !!!!!!!!!!!!!!!!! For now, hard code the MAC address. Its annoying when it keeps changing during development! - // TODO: Remove this hard-coded address - LOGTRACE("%s m_mac_addr[0]=0x00;", __PRETTY_FUNCTION__); - m_mac_addr[0]=0x00; - m_mac_addr[1]=0x80; - m_mac_addr[2]=0x19; - m_mac_addr[3]=0x10; - m_mac_addr[4]=0x98; - m_mac_addr[5]=0xE3; - -#endif // RASCSI && !BAREMETAL - LOGTRACE("SCSIDaynaPort Constructor End"); - -} - -//--------------------------------------------------------------------------- -// -// Destructor -// -//--------------------------------------------------------------------------- -SCSIDaynaPort::~SCSIDaynaPort() -{ - LOGTRACE("SCSIDaynaPort Destructor"); - // TAP driver release - if (m_tap) { - m_tap->Cleanup(); - delete m_tap; - } -} - -//--------------------------------------------------------------------------- -// -// INQUIRY -// -//--------------------------------------------------------------------------- -int FASTCALL SCSIDaynaPort::Inquiry( - const DWORD *cdb, BYTE *buffer, DWORD major, DWORD minor) -{ - DWORD allocation_length; - // scsi_cdb_6_byte_t command; - // memcpy(&command,cdb,sizeof(command)); - - ASSERT(this); - ASSERT(cdb); - ASSERT(buffer); - ASSERT(cdb[0] == 0x12); - - //allocation_length = command->length; - allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8); - // if(allocation_length != command.length){ - // LOGDEBUG("%s CDB: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__, (unsigned int)cdb[0], (unsigned int)cdb[1], (unsigned int)cdb[2], (unsigned int)cdb[3], (unsigned int)cdb[4], (unsigned int)cdb[5] ); - // LOGWARN(":::::::::: Expected allocation length %04X but found %04X", (unsigned int)allocation_length, (unsigned int)command.length); - // LOGWARN(":::::::::: Doing runtime pointer conversion: %04X", ((scsi_cdb_6_byte_t*)cdb)->length); - // } - - LOGTRACE("%s Inquiry with major %ld, minor %ld. Allocaiton length: %d",__PRETTY_FUNCTION__, major, minor, (int)allocation_length); - - if(cdb[1] & 0x3) { - LOGWARN("Tiny SCSI Emulator says this is an invalid request"); - } - - if(allocation_length > 4){ - // Copy the pre-canned response - memcpy(buffer, m_target_ethernet_inquiry_response, allocation_length); - // Set the size - //buffer[4] = (BYTE)((allocation_length - 7) & 0xFF); - // The inquiry response format only allows for a 1 byte 'additional size' field - if(allocation_length > 0xFF){ - LOGWARN("%s The inquiry format only allows for a maximum of %d (0xFF + 4) bytes",\ - __PRETTY_FUNCTION__, (int)0xFF + 4) - } - } - - LOGTRACE("response size is %d", (int)allocation_length); - - // Success - disk.code = DISK_NOERROR; - return allocation_length; -} - -//--------------------------------------------------------------------------- -// -// RequestSense -// -//--------------------------------------------------------------------------- -int FASTCALL SCSIDaynaPort::RequestSense(const DWORD *cdb, BYTE *buffer) -{ - // The DaynaPort RequestSense response will always be 9 bytes. - int size = 9; - - LOGTRACE("%s size of sense data = %d", __PRETTY_FUNCTION__, size); - - // Clear the buffer - memset(buffer, 0, size); - - // Only set the response code (70h) - buffer[0] = 0x70; - - // Clear the code - disk.code = 0x00; - - return size; -} - -//--------------------------------------------------------------------------- -// -// READ -// -//--------------------------------------------------------------------------- -int FASTCALL SCSIDaynaPort::Read(const DWORD *cdb, BYTE *buf, DWORD block) -{ - WORD requested_length = 0; - int rx_packet_size = 0; - BOOL send_message_to_host; - scsi_resp_read_t *response = (scsi_resp_read_t*)buf; - scsi_cmd_read_6_t *command = (scsi_cmd_read_6_t*)cdb; - int read_count = 0; - - ASSERT(this); - ASSERT(buf); - - LOGTRACE("%s reading DaynaPort block %lu", __PRETTY_FUNCTION__, block); - - if(command->operation_code != 0x08){ - LOGERROR("Received unexpected cdb command: %02X. Expected 0x08", (unsigned int)command->operation_code); - } - - requested_length = (WORD)command->transfer_length; - LOGTRACE("%s Read maximum length %d, (%04X)", __PRETTY_FUNCTION__, (unsigned int)requested_length, (unsigned int)requested_length); - - - // At host startup, it will send a READ(6) command with a length of 1. We should - // respond by going into the status mode with a code of 0x02 - if(requested_length == 1){ - return 0; - } - - // Some of the packets we receive will not be for us. So, we'll keep pulling messages - // until the buffer is empty, or we've read X times. (X is just a made up number) - while(read_count < 50) - { - read_count++; - - // The first 2 bytes are reserved for the length of the packet - // The next 4 bytes are reserved for a flag field - //rx_packet_size = m_tap->Rx(response->data); - rx_packet_size = m_tap->Rx(&buf[m_read_header_size]); - - // If we didn't receive anything, return size of 0 - if(rx_packet_size <= 0){ - LOGTRACE("%s No packet received", __PRETTY_FUNCTION__); - response->length = 0; - response->flags = e_no_more_data; - return m_read_header_size; - } - - LOGTRACE("%s Packet Sz %d (%08X) read: %d", __PRETTY_FUNCTION__, (unsigned int) rx_packet_size, (unsigned int) rx_packet_size, read_count); - - // This is a very basic filter to prevent unnecessary packets from - // being sent to the SCSI initiator. - send_message_to_host = FALSE; - - // Check if received packet destination MAC address matches the - // DaynaPort MAC. For IP packets, the mac_address will be the first 6 bytes - // of the data. - if (memcmp(response->data, m_mac_addr, 6) == 0) { - send_message_to_host = TRUE; - } - - // Check to see if this is a broadcast message - if (memcmp(response->data, m_bcast_addr, 6) == 0) { - send_message_to_host = TRUE; - } - - // Check to see if this is an AppleTalk Message - if (memcmp(response->data, m_apple_talk_addr, 6) == 0) { - - send_message_to_host = TRUE; - } - - // TODO: We should check to see if this message is in the multicast - // configuration from SCSI command 0x0D - - if(!send_message_to_host){ - LOGDEBUG("%s Received a packet that's not for me: %02X %02X %02X %02X %02X %02X", \ - __PRETTY_FUNCTION__, - (int)response->data[0], - (int)response->data[1], - (int)response->data[2], - (int)response->data[3], - (int)response->data[4], - (int)response->data[5]); - - // If there are pending packets to be processed, we'll tell the host that the read - // length was 0. - if(!m_tap->PendingPackets()) - { - response->length = 0; - response->flags = e_no_more_data; - return m_read_header_size; - } - } - else - { - - // TODO: Need to do some sort of size checking. The buffer can easily overflow, probably. - - - // response->length = rx_packet_size; - // if(m_tap->PendingPackets()){ - // response->flags = e_more_data_available; - // } else { - // response->flags = e_no_more_data; - // } - buf[0] = (BYTE)((rx_packet_size >> 8) & 0xFF); - buf[1] = (BYTE)(rx_packet_size & 0xFF); - - buf[2] = 0; - buf[3] = 0; - buf[4] = 0; - if(m_tap->PendingPackets()){ - buf[5] = 0x10; - } else { - buf[5] = 0; - } - - // Return the packet size + 2 for the length + 4 for the flag field - // The CRC was already appended by the ctapdriver - return rx_packet_size + m_read_header_size; - } - // If we got to this point, there are still messages in the queue, so - // we should loop back and get the next one. - } // end while - - response->length = 0; - response->flags = e_no_more_data; - return m_read_header_size; -} - -//--------------------------------------------------------------------------- -// -// WRITE check -// -//--------------------------------------------------------------------------- -int FASTCALL SCSIDaynaPort::WriteCheck(DWORD block) -{ - LOGTRACE("%s block: %lu", __PRETTY_FUNCTION__, block); - - // Status check - if (!CheckReady()) { - return 0; - } - - if(!m_bTapEnable){ - disk.code = DISK_NOTREADY; - return 0; - } - - // Success - return 1; -} - - -//--------------------------------------------------------------------------- -// -// Write -// -//--------------------------------------------------------------------------- -BOOL FASTCALL SCSIDaynaPort::Write(const DWORD *cdb, const BYTE *buf, DWORD block) -{ - BYTE data_format; - WORD data_length; - // const scsi_cmd_daynaport_write_t* command = (const scsi_cmd_daynaport_write_t*)cdb; - - data_format = cdb[5]; - data_length = (WORD)cdb[4] + ((WORD)cdb[3] << 8); - - // if(data_format != command->format){ - // LOGDEBUG("%s CDB: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__, (unsigned int)cdb[0], (unsigned int)cdb[1], (unsigned int)cdb[2], (unsigned int)cdb[3], (unsigned int)cdb[4], (unsigned int)cdb[5] ); - // LOGWARN("Expected data_format: %02X, but found %02X", (unsigned int)cdb[5], (unsigned int)command->format); - // } - // if(data_length != command->length){ - // LOGDEBUG("%s CDB: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__, (unsigned int)cdb[0], (unsigned int)cdb[1], (unsigned int)cdb[2], (unsigned int)cdb[3], (unsigned int)cdb[4], (unsigned int)cdb[5] ); - // LOGWARN("Expected data_length: %04X, but found %04X", data_length, (unsigned int)command->length); - // } - - if(data_format == 0x00){ - m_tap->Tx(buf, data_length); - LOGTRACE("%s Transmitted %u bytes (00 format)", __PRETTY_FUNCTION__, data_length); - return TRUE; - } - else if (data_format == 0x80){ - // The data length is actuall specified in the first 2 bytes of the payload - data_length=(WORD)buf[1] + ((WORD)buf[0] << 8); - m_tap->Tx(&buf[4], data_length); - LOGTRACE("%s Transmitted %u bytes (80 format)", __PRETTY_FUNCTION__, data_length); - return TRUE; - } - else - { - // LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)command->format); - LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, (unsigned int)data_format); - return FALSE; - } - -} - - -//--------------------------------------------------------------------------- -// -// RetrieveStats -// -//--------------------------------------------------------------------------- -int FASTCALL SCSIDaynaPort::RetrieveStats(const DWORD *cdb, BYTE *buffer) -{ - DWORD response_size; - DWORD allocation_length; - - // DWORD frame_alignment_errors; - // DWORD crc_errors; - // DWORD frames_lost; - - LOGTRACE("%s RetrieveStats ", __PRETTY_FUNCTION__); - - ASSERT(this); - ASSERT(cdb); - ASSERT(buffer); - - allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8); - LOGTRACE("%s Retrieve Stats buffer size was %d", __PRETTY_FUNCTION__, (int)allocation_length); - - // // ASSERT(cdb[0] == 0x09); - - // if(cdb[0] != 0x09) - // { - // LOGWARN("%s cdb[0] was not 0x09, as I expected. It was %02X.", __PRETTY_FUNCTION__, (unsigned int)cdb[0]); - // } - // if(cdb[4] != 0x12) - // { - // LOGWARN("%s cdb[4] was not 0x12, as I expected. It was %02X.", __PRETTY_FUNCTION__, (unsigned int)cdb[4]); - // } - - // memset(buffer,0,18); - - // memcpy(&buffer[0],m_mac_addr,sizeof(m_mac_addr)); - // // frame alignment errors - // frame_alignment_errors = htonl(0); - // memcpy(&(buffer[6]),&frame_alignment_errors,sizeof(frame_alignment_errors)); - // // CRC errors - // crc_errors = htonl(0); - // memcpy(&(buffer[10]),&crc_errors,sizeof(crc_errors)); - // // frames lost - // frames_lost = htonl(0); - // memcpy(&(buffer[14]),&frames_lost,sizeof(frames_lost)); - - for(int i=0; i< 6; i++) - { - LOGTRACE("%s CDB byte %d: %02X",__PRETTY_FUNCTION__, i, (unsigned int)cdb[i]); - } - - response_size = 18; - - - response_size = sizeof(m_scsi_link_stats); - memcpy(buffer, &m_scsi_link_stats, sizeof(m_scsi_link_stats)); - - LOGTRACE("%s response size is %d", __PRETTY_FUNCTION__, (int)response_size); - - if(response_size > allocation_length) - { - response_size = allocation_length; - LOGINFO("%s Truncating the inquiry response", __PRETTY_FUNCTION__) - } - - // Success - disk.code = DISK_NOERROR; - return response_size; - // scsi_cdb_6_byte_t *command = (scsi_cdb_6_byte_t*)cdb; - // scsi_resp_link_stats_t *response = (scsi_resp_link_stats_t*) buffer; - - // LOGTRACE("%s Retrieve Stats buffer size was %d", __PRETTY_FUNCTION__, command->length); - - // ASSERT(sizeof(scsi_resp_link_stats_t) == 18); - - // memcpy(response->mac_address, m_mac_addr, sizeof(m_mac_addr)); - // response->crc_errors = 0; - // response->frames_lost = 0; - // response->frame_alignment_errors = 0; - - // // Success - // disk.code = DISK_NOERROR; - // return sizeof(scsi_resp_link_stats_t); -} - -//--------------------------------------------------------------------------- -// -// Enable or Disable the interface -// -//--------------------------------------------------------------------------- -BOOL FASTCALL SCSIDaynaPort::EnableInterface(const DWORD *cdb) -{ - int result; - // scsi_cdb_6_byte_t *command = (scsi_cdb_6_byte_t*)cdb; - - // if(command->control & 0x80) - if(cdb[5] & 0x80) - - { - result = m_tap->Enable(); - if(result){ - LOGINFO("The DaynaPort interface has been ENABLED."); - } - else{ - LOGWARN("Unable to enable the DaynaPort Interface"); - } - m_tap->Flush(); - } - else - { - result = m_tap->Disable(); - if(result){ - LOGINFO("The DaynaPort interface has been DISABLED."); - } - else{ - LOGWARN("Unable to disable the DaynaPort Interface"); - } - } - - return TRUE; -} - -//--------------------------------------------------------------------------- -// -// TEST UNIT READY -// -//--------------------------------------------------------------------------- -BOOL FASTCALL SCSIDaynaPort::TestUnitReady(const DWORD* /*cdb*/) -{ - ASSERT(this); - LOGTRACE("%s", __PRETTY_FUNCTION__); - - // TEST UNIT READY Success - disk.code = DISK_NOERROR; - return TRUE; -} - -//--------------------------------------------------------------------------- -// -// Set Mode - enable broadcast messages -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIDaynaPort::SetMode(const DWORD *cdb, BYTE *buffer) -{ - LOGTRACE("%s Setting mode", __PRETTY_FUNCTION__); - - for(size_t i=0; i= 0); - return Disk::Read(cdb, buf, block); + return Disk::Read(buf, block); } //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/devices/scsicd.h b/src/raspberrypi/devices/scsicd.h index 2ccd9b52..ca4b9070 100644 --- a/src/raspberrypi/devices/scsicd.h +++ b/src/raspberrypi/devices/scsicd.h @@ -122,7 +122,7 @@ private: // Wave path BOOL valid; // Open result (is it valid?) - DWORD *m_buf; + DWORD *buf; // Data buffer DWORD read; // Read pointer @@ -164,7 +164,7 @@ public: // commands int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command - int FASTCALL Read(const DWORD *cdb, BYTE *buf, DWORD block) override; + int FASTCALL Read(BYTE *buf, DWORD block); // READ command int FASTCALL ReadToc(const DWORD *cdb, BYTE *buf); // READ TOC command diff --git a/src/raspberrypi/devices/scsihd.cpp b/src/raspberrypi/devices/scsihd.cpp index f7e7545b..ed4c32b1 100644 --- a/src/raspberrypi/devices/scsihd.cpp +++ b/src/raspberrypi/devices/scsihd.cpp @@ -100,7 +100,7 @@ BOOL FASTCALL SCSIHD::Open(const Filepath& path, BOOL /*attn*/) // INQUIRY // //--------------------------------------------------------------------------- -int FASTCALL SCSIHD:: Inquiry( +int FASTCALL SCSIHD::Inquiry( const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor) { char vendor[32]; @@ -241,7 +241,7 @@ BOOL FASTCALL SCSIHD::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) case 0x08: // Debug code for Issue #2: // https://github.com/akuker/RASCSI/issues/2 - LOGWARN("[Unhandled page code] Received mode page code 8 with total length %d\n ", length); + printf("[Unhandled page code] Received mode page code 8 with total length %d\n ", length); for (int i = 0; i - - -//--------------------------------------------------------------------------- -// -// Run system command and wait for it to finish -// -//--------------------------------------------------------------------------- -int run_system_cmd(const char* command) -{ - pid_t pid; - int result; - int status = 0; - pid=fork(); - if(pid == 0){ - result = system(command); - exit(result); - } - waitpid(pid, &status, 0); - return status; -} \ No newline at end of file diff --git a/src/raspberrypi/os.h b/src/raspberrypi/os.h index 9cb9f31e..e1da949e 100644 --- a/src/raspberrypi/os.h +++ b/src/raspberrypi/os.h @@ -5,11 +5,10 @@ // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS -// Copyright (C) 2020 akuker // // Imported NetBSD support and some optimisation patch by Rin Okuyama. // -// [ OS related definitions ] +// [ OS固有 ] // //--------------------------------------------------------------------------- @@ -87,7 +86,7 @@ //--------------------------------------------------------------------------- // -// Basic Macros +// 基本マクロ // //--------------------------------------------------------------------------- #undef FASTCALL @@ -119,7 +118,7 @@ //--------------------------------------------------------------------------- // -// Basic Type Definitions +// 基本型定義 // //--------------------------------------------------------------------------- typedef unsigned char BYTE; @@ -155,7 +154,4 @@ typedef const char *LPCSTR; #define xstrcasecmp strcasecmp #define xstrncasecmp strncasecmp -// Run system command and wait for it to finish -extern int run_system_cmd(const char* command); - #endif // os_h diff --git a/src/raspberrypi/os_integration/rascsi.service b/src/raspberrypi/os_integration/rascsi.service index 62fe6528..d5072387 100644 --- a/src/raspberrypi/os_integration/rascsi.service +++ b/src/raspberrypi/os_integration/rascsi.service @@ -9,7 +9,7 @@ ExecStart=/usr/local/bin/rascsi # Example: If you want to automatically attach a hard disk at startup, change # the ExecStart line to: # ExecStart=/usr/local/bin/rascsi -ID1 /home/pi/images/harddisk.hda -# This functionality isn't implmented yet: ExecStop=/usr/local/bin/rasctl -stop +ExecStop=/usr/local/bin/rasctl -stop StandardOutput=syslog StandardError=syslog SyslogIdentifier=RASCSI diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index 3d30448e..8fc44ae1 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -21,15 +21,11 @@ #include "devices/scsicd.h" #include "devices/scsimo.h" #include "devices/scsi_host_bridge.h" -#include "devices/scsi_daynaport.h" #include "controllers/scsidev_ctrl.h" #include "controllers/sasidev_ctrl.h" #include "gpiobus.h" #include "rascsi_version.h" -#include "rasctl.h" #include "spdlog/spdlog.h" -#include "spdlog/sinks/stdout_color_sinks.h" -#include //--------------------------------------------------------------------------- // @@ -99,7 +95,7 @@ void Banner(int argc, char* argv[]) FPRT(stdout," FILE is disk image file.\n\n"); FPRT(stdout,"Usage: %s [-HDn FILE] ...\n\n", argv[0]); FPRT(stdout," n is X68000 SASI HD number(0-15).\n"); - FPRT(stdout," FILE is disk image file, \"daynaport\", or \"bridge\".\n\n"); + FPRT(stdout," FILE is disk image file.\n\n"); FPRT(stdout," Image type is detected based on file extension.\n"); FPRT(stdout," hdf : SASI HD image(XM6 SASI HD image)\n"); FPRT(stdout," hds : SCSI HD image(XM6 SCSI HD image)\n"); @@ -266,12 +262,10 @@ void ListDevice(FILE *fp) Filepath filepath; BOOL find; char type[5]; - char dev_status[_MAX_FNAME+26]; find = FALSE; type[4] = 0; for (i = 0; i < CtrlMax * UnitNum; i++) { - strncpy(dev_status,"",sizeof(dev_status)); // Initialize ID and unit number id = i / UnitNum; un = i % UnitNum; @@ -286,9 +280,7 @@ void ListDevice(FILE *fp) if (!find) { FPRT(fp, "\n"); FPRT(fp, "+----+----+------+-------------------------------------\n"); - LOGINFO( "+----+----+------+-------------------------------------"); FPRT(fp, "| ID | UN | TYPE | DEVICE STATUS\n"); - LOGINFO( "| ID | UN | TYPE | DEVICE STATUS\n"); FPRT(fp, "+----+----+------+-------------------------------------\n"); find = TRUE; } @@ -298,26 +290,25 @@ void ListDevice(FILE *fp) 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')) { - strncpy(dev_status,"X68000 HOST BRIDGE",sizeof(dev_status)); - } else if (pUnit->GetID() == MAKEID('S', 'C', 'D', 'P')) { - strncpy(dev_status,"DaynaPort SCSI/Link",sizeof(dev_status)); + FPRT(fp, "%s", "HOST BRIDGE"); } else { pUnit->GetPath(filepath); - snprintf(dev_status, sizeof(dev_status), "%s", + FPRT(fp, "%s", (pUnit->IsRemovable() && !pUnit->IsReady()) ? "NO MEDIA" : filepath.GetPath()); } // Write protection status if (pUnit->IsRemovable() && pUnit->IsReady() && pUnit->IsWriteP()) { - strcat(dev_status, "(WRITEPROTECT)"); + FPRT(fp, "(WRITEPROTECT)"); } - FPRT(fp, "| %d | %d | %s | %s\n", id, un, type, dev_status); - LOGINFO( "| %d | %d | %s | %s", id, un, type, dev_status); + // Goto the next line + FPRT(fp, "\n"); } // If there is no controller, find will be null @@ -327,7 +318,6 @@ void ListDevice(FILE *fp) } FPRT(fp, "+----+----+------+-------------------------------------\n"); - LOGINFO( "+----+----+------+-------------------------------------"); } //--------------------------------------------------------------------------- @@ -457,7 +447,6 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) char *ext; Filepath filepath; Disk *pUnit; - char type_str[5]; // Copy the Unit List memcpy(map, disk, sizeof(disk)); @@ -479,7 +468,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) // Distinguish between SASI and SCSI ext = NULL; pUnit = NULL; - if (type == rasctl_dev_sasi_hd) { + if (type == 0) { // Passed the check if (!file) { return FALSE; @@ -499,16 +488,16 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) // If the extension is not SASI type, replace with SCSI ext = &file[len - 3]; if (xstrcasecmp(ext, "hdf") != 0) { - type = rasctl_dev_scsi_hd; + type = 1; } } // Create a new drive, based upon type switch (type) { - case rasctl_dev_sasi_hd: // HDF + case 0: // HDF pUnit = new SASIHD(); break; - case rasctl_dev_scsi_hd: // HDS/HDN/HDI/NHD/HDA + case 1: // HDS/HDN/HDI/NHD/HDA if (ext == NULL) { break; } @@ -521,37 +510,28 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) pUnit = new SCSIHD(); } break; - case rasctl_dev_mo: // MO + case 2: // MO pUnit = new SCSIMO(); break; - case rasctl_dev_cd: // CD + case 3: // CD pUnit = new SCSICD(); break; - case rasctl_dev_br: // BRIDGE + case 4: // BRIDGE pUnit = new SCSIBR(); break; - // case rasctl_dev_nuvolink: // Nuvolink - // pUnit = new SCSINuvolink(); - // break; - case rasctl_dev_daynaport: // DaynaPort SCSI Link - pUnit = new SCSIDaynaPort(); - LOGTRACE("Done creating SCSIDayanPort"); - break; default: FPRT(fp, "Error : Invalid device type\n"); - LOGWARN("rasctl sent a command for an invalid drive type: %d", type); return FALSE; } // drive checks files - if (type <= rasctl_dev_scsi_hd || (type <= rasctl_dev_cd && xstrcasecmp(file, "-") != 0)) { + if (type <= 1 || (type <= 3 && xstrcasecmp(file, "-") != 0)) { // Set the Path filepath.SetPath(file); // Open the file path if (!pUnit->Open(filepath)) { FPRT(fp, "Error : File open error [%s]\n", file); - LOGWARN("rasctl tried to open an invalid file %s", file); delete pUnit; return FALSE; } @@ -565,26 +545,18 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) // Re-map the controller MapControler(fp, map); - 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); return TRUE; } // Is this a valid command? if (cmd > 4) { FPRT(fp, "Error : Invalid command\n"); - LOGINFO("rasctl sent an invalid command: %d",cmd); return FALSE; } // Does the controller exist? if (ctrl[id] == NULL) { FPRT(fp, "Error : No such device\n"); - LOGWARN("rasctl sent a command for invalid controller %d", id); return FALSE; } @@ -592,24 +564,11 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) pUnit = disk[id * UnitNum + un]; if (pUnit == NULL) { FPRT(fp, "Error : No such device\n"); - LOGWARN("rasctl sent a command for invalid unit ID %d UN %d", id, un); return FALSE; } - type_str[0] = (char)(map[id * UnitNum + un]->GetID() >> 24); - type_str[1] = (char)(map[id * UnitNum + un]->GetID() >> 16); - type_str[2] = (char)(map[id * UnitNum + un]->GetID() >> 8); - type_str[3] = (char)(map[id * UnitNum + un]->GetID()); - type_str[4] = '\0'; - // Disconnect Command if (cmd == 1) { // DETACH - type_str[0] = (char)(map[id * UnitNum + un]->GetID() >> 24); - type_str[1] = (char)(map[id * UnitNum + un]->GetID() >> 16); - type_str[2] = (char)(map[id * UnitNum + un]->GetID() >> 8); - type_str[3] = (char)(map[id * UnitNum + un]->GetID()); - type_str[4] = '\0'; - LOGINFO("rasctl command disconnect %s at ID: %d UN: %d", type_str, id, un); // Free the existing unit map[id * UnitNum + un] = NULL; @@ -621,8 +580,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) // Valid only for MO or CD if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O') && pUnit->GetID() != MAKEID('S', 'C', 'C', 'D')) { - FPRT(fp, "Error : Operation denied (Device type %s isn't removable)\n", type_str); - LOGWARN("rasctl sent an Insert/Eject/Protect command (%d) for incompatible type %s", cmd, type_str); + FPRT(fp, "Error : Operation denied(Deveice isn't removable)\n"); return FALSE; } @@ -630,7 +588,6 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) case 2: // INSERT // Set the file path filepath.SetPath(file); - LOGINFO("rasctl commanded insert file %s into %s ID: %d UN: %d", file, type_str, id, un); // Open the file if (!pUnit->Open(filepath)) { @@ -640,21 +597,17 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) break; case 3: // EJECT - LOGINFO("rasctl commands eject %s ID: %d UN: %d", type_str, id, un); pUnit->Eject(TRUE); break; case 4: // PROTECT if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O')) { FPRT(fp, "Error : Operation denied(Deveice isn't MO)\n"); - LOGWARN("rasctl sent an invalid PROTECT command for %s ID: %d UN: %d", type_str, id, un); return FALSE; } - LOGINFO("rasctl is setting write protect to %d for %s ID: %d UN: %d",!pUnit->IsWriteP(), type_str, id, un); pUnit->WriteP(!pUnit->IsWriteP()); break; default: - LOGWARN("Received unknown command from rasctl: %d", cmd); ASSERT(FALSE); return FALSE; } @@ -1111,9 +1064,6 @@ int main(int argc, char* argv[]) #endif // BAREMETAL spdlog::set_level(spdlog::level::trace); - // Create a thread-safe stdout logger to process the log messages - auto logger = spdlog::stdout_color_mt("rascsi stdout logger"); - LOGTRACE("Entering the function %s with %d arguments", __PRETTY_FUNCTION__, argc); // Output the Banner Banner(argc, argv); diff --git a/src/raspberrypi/rasctl.cpp b/src/raspberrypi/rasctl.cpp index 406b814f..c99e5d01 100644 --- a/src/raspberrypi/rasctl.cpp +++ b/src/raspberrypi/rasctl.cpp @@ -11,7 +11,6 @@ #include "os.h" #include "rascsi_version.h" -#include "rasctl.h" //--------------------------------------------------------------------------- // @@ -96,7 +95,7 @@ int main(int argc, char* argv[]) fprintf(stderr, " where ID := {0|1|2|3|4|5|6|7}\n"); fprintf(stderr, " UNIT := {0|1} default setting is 0.\n"); fprintf(stderr, " CMD := {attach|detach|insert|eject|protect}\n"); - fprintf(stderr, " TYPE := {hd|mo|cd|bridge|daynaport}\n"); + fprintf(stderr, " TYPE := {hd|mo|cd|bridge}\n"); fprintf(stderr, " FILE := image file path\n"); fprintf(stderr, " CMD is 'attach' or 'insert' and FILE parameter is required.\n"); fprintf(stderr, "Usage: %s -l\n", argv[0]); @@ -147,29 +146,19 @@ int main(int argc, char* argv[]) case 'S': case 'h': // HD(SCSI) case 'H': - // rascsi will figure out if this should be SASI or - // SCSI later in the process.... - type = rasctl_dev_sasi_hd; + type = 0; break; case 'm': // MO case 'M': - type = rasctl_dev_mo; + type = 2; break; case 'c': // CD case 'C': - type = rasctl_dev_cd; + type = 3; break; case 'b': // BRIDGE case 'B': - type = rasctl_dev_br; - break; - // case 'n': // Nuvolink - // case 'N': - // type = rasctl_dev_nuvolink; - // break; - case 'd': // DaynaPort - case 'D': - type = rasctl_dev_daynaport; + type = 4; break; } break; @@ -193,13 +182,13 @@ int main(int argc, char* argv[]) // Check the ID number if (id < 0 || id > 7) { - fprintf(stderr, "%s Error : Invalid ID %d \n", __PRETTY_FUNCTION__, id); + fprintf(stderr, "Error : Invalid ID\n"); exit(EINVAL); } // Check the unit number if (un < 0 || un > 1) { - fprintf(stderr, "%s Error : Invalid UNIT %d \n", __PRETTY_FUNCTION__, un); + fprintf(stderr, "Error : Invalid UNIT\n"); exit(EINVAL); } diff --git a/src/raspberrypi/rasctl.h b/src/raspberrypi/rasctl.h deleted file mode 100644 index a56e95dd..00000000 --- a/src/raspberrypi/rasctl.h +++ /dev/null @@ -1,24 +0,0 @@ -//--------------------------------------------------------------------------- -// -// SCSI Target Emulator RaSCSI (*^..^*) -// for Raspberry Pi -// -// Powered by XM6 TypeG Technology. -// Copyright (C) 2016-2020 GIMONS -// Copyright (C) akuker -// -// [ Send Control Command ] -// -//--------------------------------------------------------------------------- - - -enum rasctl_dev_type : int { - rasctl_dev_invalid = -1, - rasctl_dev_sasi_hd = 0, - rasctl_dev_scsi_hd = 1, - rasctl_dev_mo = 2, - rasctl_dev_cd = 3, - rasctl_dev_br = 4, - rasctl_dev_nuvolink = 5, - rasctl_dev_daynaport = 6, -}; diff --git a/src/raspberrypi/rasdump.cpp b/src/raspberrypi/rasdump.cpp index 4d6d60e0..776103dc 100644 --- a/src/raspberrypi/rasdump.cpp +++ b/src/raspberrypi/rasdump.cpp @@ -5,7 +5,7 @@ // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS -// [ HDD dump utility (initiator mode) ] +// [ HDDダンプユーティリティ(イニシーエタモード) ] // //--------------------------------------------------------------------------- @@ -18,46 +18,46 @@ //--------------------------------------------------------------------------- // -// Constant Declaration +// 定数宣言 // //--------------------------------------------------------------------------- -#define BUFSIZE 1024 * 64 // Buffer size of about 64KB +#define BUFSIZE 1024 * 64 // 64KBぐらいかなぁ //--------------------------------------------------------------------------- // -// Variable Declaration +// 変数宣言 // //--------------------------------------------------------------------------- -GPIOBUS bus; // Bus -int targetid; // Target ID -int boardid; // Board ID (own ID) -Filepath hdsfile; // HDS file -BOOL restore; // Restore flag -BYTE buffer[BUFSIZE]; // Work Buffer -int result; // Result Code +GPIOBUS bus; // バス +int targetid; // ターゲットデバイスID +int boardid; // ボードID(自身のID) +Filepath hdsfile; // HDSファイル +BOOL restore; // リストアフラグ +BYTE buffer[BUFSIZE]; // ワークバッファ +int result; // 結果コード //--------------------------------------------------------------------------- // -// Cleanup() Function declaration +// 関数宣言 // //--------------------------------------------------------------------------- void Cleanup(); //--------------------------------------------------------------------------- // -// Signal processing +// シグナル処理 // //--------------------------------------------------------------------------- void KillHandler(int sig) { - // Stop running + // 停止指示 Cleanup(); exit(0); } //--------------------------------------------------------------------------- // -// Banner Output +// バナー出力 // //--------------------------------------------------------------------------- BOOL Banner(int argc, char* argv[]) @@ -82,12 +82,12 @@ BOOL Banner(int argc, char* argv[]) //--------------------------------------------------------------------------- // -// Initialization +// 初期化 // //--------------------------------------------------------------------------- BOOL Init() { - // Interrupt handler setting + // 割り込みハンドラ設定 if (signal(SIGINT, KillHandler) == SIG_ERR) { return FALSE; } @@ -98,12 +98,12 @@ BOOL Init() return FALSE; } - // GPIO Initialization + // GPIO初期化 if (!bus.Init(BUS::INITIATOR)) { return FALSE; } - // Work Intitialization + // ワーク初期化 targetid = -1; boardid = 7; restore = FALSE; @@ -113,29 +113,29 @@ BOOL Init() //--------------------------------------------------------------------------- // -// Cleanup +// クリーンアップ // //--------------------------------------------------------------------------- void Cleanup() { - // Cleanup the bus + // バスをクリーンアップ bus.Cleanup(); } //--------------------------------------------------------------------------- // -// Reset +// リセット // //--------------------------------------------------------------------------- void Reset() { - // Reset the bus signal line + // バス信号線をリセット bus.Reset(); } //--------------------------------------------------------------------------- // -// Argument processing +// 引数処理 // //--------------------------------------------------------------------------- BOOL ParseArgument(int argc, char* argv[]) @@ -143,10 +143,10 @@ BOOL ParseArgument(int argc, char* argv[]) int opt; char *file; - // Initialization + // 初期化 file = NULL; - // Argument Parsing + // 引数解析 opterr = 0; while ((opt = getopt(argc, argv, "i:b:f:r")) != -1) { switch (opt) { @@ -168,28 +168,28 @@ BOOL ParseArgument(int argc, char* argv[]) } } - // TARGET ID check + // TARGET IDチェック if (targetid < 0 || targetid > 7) { fprintf(stderr, "Error : Invalid target id range\n"); return FALSE; } - // BOARD ID check + // BOARD IDチェック if (boardid < 0 || boardid > 7) { fprintf(stderr, "Error : Invalid board id range\n"); return FALSE; } - // Target and Board ID duplication check + // TARGETとBOARDのID重複チェック if (targetid == boardid) { fprintf(stderr, "Error : Invalid target or board id\n"); return FALSE; } - // File Check + // ファイルチェック if (!file) { fprintf(stderr, "Error : Invalid file path\n"); @@ -203,14 +203,14 @@ BOOL ParseArgument(int argc, char* argv[]) //--------------------------------------------------------------------------- // -// Wait Phase +// フェーズ待ち // //--------------------------------------------------------------------------- BOOL WaitPhase(BUS::phase_t phase) { DWORD now; - // Timeout (3000ms) + // タイムアウト(3000ms) now = SysTimer::GetTimerLow(); while ((SysTimer::GetTimerLow() - now) < 3 * 1000 * 1000) { bus.Aquire(); @@ -224,18 +224,18 @@ BOOL WaitPhase(BUS::phase_t phase) //--------------------------------------------------------------------------- // -// Bus Free Phase +// バスフリーフェーズ実行 // //--------------------------------------------------------------------------- void BusFree() { - // Bus Reset + // バスリセット bus.Reset(); } //--------------------------------------------------------------------------- // -// Selection Phase +// セレクションフェーズ実行 // //--------------------------------------------------------------------------- BOOL Selection(int id) @@ -243,14 +243,14 @@ BOOL Selection(int id) BYTE data; int count; - // ID setting and SEL assert + // ID設定とSELアサート data = 0; data |= (1 << boardid); data |= (1 << id); bus.SetDAT(data); bus.SetSEL(TRUE); - // wait for busy + // BSYを待つ count = 10000; do { usleep(20); @@ -260,128 +260,127 @@ BOOL Selection(int id) } } while (count--); - // SEL negate + // SELネゲート bus.SetSEL(FALSE); - // Success if the target is busy + // ターゲットがビジー状態なら成功 return bus.GetBSY(); } //--------------------------------------------------------------------------- // -// Command Phase +// コマンドフェーズ実行 // //--------------------------------------------------------------------------- BOOL Command(BYTE *buf, int length) { int count; - // Waiting for Phase + // フェーズ待ち if (!WaitPhase(BUS::command)) { return FALSE; } - // Send Command + // コマンド送信 count = bus.SendHandShake(buf, length); - // Success if the transmission result is the same as the number - // of requests + // 送信結果が依頼数と同じなら成功 if (count == length) { return TRUE; } - // Return error + // 送信エラー return FALSE; } //--------------------------------------------------------------------------- // -// Data in phase +// データインフェーズ実行 // //--------------------------------------------------------------------------- int DataIn(BYTE *buf, int length) { - // Wait for phase + // フェーズ待ち if (!WaitPhase(BUS::datain)) { return -1; } - // Data reception + // データ受信 return bus.ReceiveHandShake(buf, length); } //--------------------------------------------------------------------------- // -// Data out phase +// データアウトフェーズ実行 // //--------------------------------------------------------------------------- int DataOut(BYTE *buf, int length) { - // Wait for phase + // フェーズ待ち if (!WaitPhase(BUS::dataout)) { return -1; } - // Data transmission + // データ受信 return bus.SendHandShake(buf, length); } //--------------------------------------------------------------------------- // -// Status Phase +// ステータスフェーズ実行 // //--------------------------------------------------------------------------- int Status() { BYTE buf[256]; - // Wait for phase + // フェーズ待ち if (!WaitPhase(BUS::status)) { return -2; } - // Data reception + // データ受信 if (bus.ReceiveHandShake(buf, 1) == 1) { return (int)buf[0]; } - // Return error + // 受信エラー return -1; } //--------------------------------------------------------------------------- // -// Message in phase +// メッセージインフェーズ実行 // //--------------------------------------------------------------------------- int MessageIn() { BYTE buf[256]; - // Wait for phase + // フェーズ待ち if (!WaitPhase(BUS::msgin)) { return -2; } - // Data reception + // データ受信 if (bus.ReceiveHandShake(buf, 1) == 1) { return (int)buf[0]; } - // Return error + // 受信エラー return -1; } //--------------------------------------------------------------------------- // -// TEST UNIT READY +// TEST UNIT READY実行 // //--------------------------------------------------------------------------- int TestUnitReady(int id) { BYTE cmd[256]; - // Result code initialization + // 結果コード初期化 result = 0; // SELECTION @@ -411,7 +410,7 @@ int TestUnitReady(int id) } exit: - // Bus free + // バスフリー BusFree(); return result; @@ -419,7 +418,7 @@ exit: //--------------------------------------------------------------------------- // -// REQUEST SENSE +// REQUEST SENSE実行 // //--------------------------------------------------------------------------- int RequestSense(int id, BYTE *buf) @@ -427,7 +426,7 @@ int RequestSense(int id, BYTE *buf) BYTE cmd[256]; int count; - // Result code initialization + // 結果コード初期化 result = 0; count = 0; @@ -467,10 +466,10 @@ int RequestSense(int id, BYTE *buf) } exit: - // Bus Free + // バスフリー BusFree(); - // Returns the number of transfers if successful + // 成功であれば転送数を返す if (result == 0) { return count; } @@ -480,7 +479,7 @@ exit: //--------------------------------------------------------------------------- // -// MODE SENSE +// MODE SENSE実行 // //--------------------------------------------------------------------------- int ModeSense(int id, BYTE *buf) @@ -488,7 +487,7 @@ int ModeSense(int id, BYTE *buf) BYTE cmd[256]; int count; - // Result code initialization + // 結果コード初期化 result = 0; count = 0; @@ -529,10 +528,10 @@ int ModeSense(int id, BYTE *buf) } exit: - // Bus free + // バスフリー BusFree(); - // Returns the number of transfers if successful + // 成功であれば転送数を返す if (result == 0) { return count; } @@ -542,7 +541,7 @@ exit: //--------------------------------------------------------------------------- // -// INQUIRY +// INQUIRY実行 // //--------------------------------------------------------------------------- int Inquiry(int id, BYTE *buf) @@ -550,7 +549,7 @@ int Inquiry(int id, BYTE *buf) BYTE cmd[256]; int count; - // Result code initialization + // 結果コード初期化 result = 0; count = 0; @@ -590,10 +589,10 @@ int Inquiry(int id, BYTE *buf) } exit: - // Bus free + // バスフリー BusFree(); - // Returns the number of transfers if successful + // 成功であれば転送数を返す if (result == 0) { return count; } @@ -603,7 +602,7 @@ exit: //--------------------------------------------------------------------------- // -// READ CAPACITY +// READ CAPACITY実行 // //--------------------------------------------------------------------------- int ReadCapacity(int id, BYTE *buf) @@ -611,7 +610,7 @@ int ReadCapacity(int id, BYTE *buf) BYTE cmd[256]; int count; - // Result code initialization + // 結果コード初期化 result = 0; count = 0; @@ -650,10 +649,10 @@ int ReadCapacity(int id, BYTE *buf) } exit: - // Bus free + // バスフリー BusFree(); - // Returns the number of transfers if successful + // 成功であれば転送数を返す if (result == 0) { return count; } @@ -663,7 +662,7 @@ exit: //--------------------------------------------------------------------------- // -// READ10 +// READ10実行 // //--------------------------------------------------------------------------- int Read10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) @@ -671,7 +670,7 @@ int Read10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) BYTE cmd[256]; int count; - // Result code initialization + // 結果コード初期化 result = 0; count = 0; @@ -715,10 +714,10 @@ int Read10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) } exit: - // Bus free + // バスフリー BusFree(); - // Returns the number of transfers if successful + // 成功であれば転送数を返す if (result == 0) { return count; } @@ -728,7 +727,7 @@ exit: //--------------------------------------------------------------------------- // -// WRITE10 +// WRITE10実行 // //--------------------------------------------------------------------------- int Write10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) @@ -736,7 +735,7 @@ int Write10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) BYTE cmd[256]; int count; - // Result code initialization + // 結果コード初期化 result = 0; count = 0; @@ -780,10 +779,10 @@ int Write10(int id, DWORD bstart, DWORD blength, DWORD length, BYTE *buf) } exit: - // Bus free + // バスフリー BusFree(); - // Returns the number of transfers if successful + // 成功であれば転送数を返す if (result == 0) { return count; } @@ -793,7 +792,7 @@ exit: //--------------------------------------------------------------------------- // -// Main process +// 主処理 // //--------------------------------------------------------------------------- int main(int argc, char* argv[]) @@ -810,32 +809,32 @@ int main(int argc, char* argv[]) Fileio::OpenMode omode; off64_t size; - // Banner output + // バナー出力 if (!Banner(argc, argv)) { exit(0); } - // Initialization + // 初期化 if (!Init()) { - fprintf(stderr, "Error : Initializing. Are you root?\n"); + fprintf(stderr, "Error : Initializing\n"); - // Probably not root + // 恐らくrootでは無い? exit(EPERM); } - // Prase Argument + // 構築 if (!ParseArgument(argc, argv)) { - // Cleanup + // クリーンアップ Cleanup(); - // Exit with invalid argument error + // 引数エラーで終了 exit(EINVAL); } - // Reset the SCSI bus + // リセット Reset(); - // File Open + // ファイルオープン if (restore) { omode = Fileio::ReadOnly; } else { @@ -844,20 +843,20 @@ int main(int argc, char* argv[]) if (!fio.Open(hdsfile.GetPath(), omode)) { fprintf(stderr, "Error : Can't open hds file\n"); - // Cleanup + // クリーンアップ Cleanup(); exit(EPERM); } - // Bus free + // バスフリー BusFree(); - // Assert reset signal + // RESETシグナル発行 bus.SetRST(TRUE); usleep(1000); bus.SetRST(FALSE); - // Start dump + // ダンプ開始 printf("TARGET ID : %d\n", targetid); printf("BORAD ID : %d\n", boardid); @@ -882,7 +881,7 @@ int main(int argc, char* argv[]) goto cleanup_exit; } - // Display INQUIRY information + // INQUIRYの情報を表示 memset(str, 0x00, sizeof(str)); memcpy(str, &buffer[8], 8); printf("Vendor : %s\n", str); @@ -893,14 +892,14 @@ int main(int argc, char* argv[]) memcpy(str, &buffer[32], 4); printf("Revison : %s\n", str); - // Get drive capacity + // 容量取得 count = ReadCapacity(targetid, buffer); if (count < 0) { fprintf(stderr, "READ CAPACITY ERROR %d\n", count); goto cleanup_exit; } - // Display block size and number of blocks + // ブロックサイズとブロック数の表示 bsiz = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; @@ -914,7 +913,7 @@ int main(int argc, char* argv[]) (int)(bsiz * bnum / 1024 / 1024), (int)(bsiz * bnum)); - // Get the restore file size + // リストアファイルサイズの取得 if (restore) { size = fio.GetFileSize(); printf("Restore file size : %d bytes", (int)size); @@ -927,7 +926,7 @@ int main(int argc, char* argv[]) printf("\n"); } - // Dump by buffer size + // バッファサイズ毎にダンプする duni = BUFSIZE; duni /= bsiz; dsiz = BUFSIZE; @@ -975,7 +974,7 @@ int main(int argc, char* argv[]) printf("\033[0K"); } - // Rounding on capacity + // 容量上の端数処理 dnum = bnum % duni; dsiz = dnum * bsiz; if (dnum > 0) { @@ -990,16 +989,16 @@ int main(int argc, char* argv[]) } } - // Completion Message + // 完了メッセージ printf("%3d%%(%7d/%7d)\n", 100, (int)bnum, (int)bnum); cleanup_exit: - // File close + // ファイルクローズ fio.Close(); - // Cleanup + // クリーンアップ Cleanup(); - // end + // 終了 exit(0); } diff --git a/src/raspberrypi/scsi.h b/src/raspberrypi/scsi.h index 906d0fd0..a1ee4259 100644 --- a/src/raspberrypi/scsi.h +++ b/src/raspberrypi/scsi.h @@ -28,13 +28,13 @@ public: }; // Phase definition - enum phase_t : BYTE { + enum phase_t { busfree, // バスフリーフェーズ arbitration, // アービトレーションフェーズ selection, // セレクションフェーズ reselection, // リセレクションフェーズ command, // コマンドフェーズ - execute, // 実行フェーズ Execute is an extension of the command phase + execute, // 実行フェーズ datain, // データイン dataout, // データアウト status, // ステータスフェーズ @@ -128,14 +128,6 @@ public: virtual int FASTCALL SendHandShake(BYTE *buf, int count) = 0; // データ送信ハンドシェイク - - virtual BOOL FASTCALL GetSignal(int pin) = 0; - // Get SCSI input signal value - virtual void FASTCALL SetSignal(int pin, BOOL ast) = 0; - // Set SCSI output signal value -protected: - phase_t m_current_phase = phase_t::reserved; - private: static const phase_t phase_table[8]; // フェーズテーブル @@ -143,84 +135,4 @@ private: static const char* phase_str_table[]; }; - -typedef struct __attribute__((packed)) { - BYTE operation_code; - BYTE misc_cdb_information; - BYTE page_code; - WORD length; - BYTE control; -} scsi_cdb_6_byte_t; - - -typedef struct __attribute__((packed)) { - BYTE operation_code; - BYTE service_action; - DWORD logical_block_address; - BYTE misc_cdb_information; - WORD length; - BYTE control; -} scsi_cdb_10_byte_t; - -typedef struct __attribute__((packed)) { - BYTE operation_code; - BYTE service_action; - DWORD logical_block_address; - DWORD length; - BYTE misc_cdb_information; - BYTE control; -} scsi_cdb_12_byte_t; - -typedef struct __attribute__((packed)) { - BYTE operation_code; - BYTE service_action; - DWORD logical_block_address; - DWORD length; - BYTE misc_cdb_information; - BYTE control; -} scsi_cdb_16_byte_t; - -typedef struct __attribute__((packed)) { - BYTE operation_code; - BYTE reserved; - BYTE page_code; - WORD allocation_length; - BYTE control; -} scsi_cmd_inquiry_t; - -typedef struct __attribute__((packed)) { - BYTE operation_code; - BYTE lba_msb_bits_4_0; - WORD logical_block_address; - BYTE transfer_length; - BYTE control; -} scsi_cmd_read_6_t; - -typedef struct __attribute__((packed)) { - BYTE operation_code; - BYTE flags; - DWORD logical_block_address; - BYTE group_number; - WORD transfer_length; - BYTE control; -} scsi_cmd_read_10_t; - -typedef struct __attribute__((packed)) { - BYTE operation_code; - BYTE flags; - DWORD logical_block_address; - DWORD transfer_length; - BYTE group_number; - BYTE control; -} scsi_cmd_read_12_t; - -typedef struct __attribute__((packed)) { - BYTE operation_code; - BYTE descriptor_format; - WORD reserved; - BYTE allocation_length; - BYTE control; -} scsi_cmd_request_sense_t; - - #endif // scsi_h diff --git a/src/raspberrypi/setup_bridge.sh b/src/raspberrypi/setup_bridge.sh deleted file mode 100755 index d81e7358..00000000 --- a/src/raspberrypi/setup_bridge.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -sudo brctl addbr rascsi_bridge -sudo brctl addif rascsi_bridge eth0 -sudo ip link set dev rascsi_bridge up - -echo Bridge config: -brctl show From 8b3cfed98c3ce0415142e8d8f41b7b2e42ce0260 Mon Sep 17 00:00:00 2001 From: Adrian Merwood Date: Sun, 21 Feb 2021 18:29:48 +0000 Subject: [PATCH 17/22] Updated oled script for Python3 --- src/oled_monitor/rascsi_oled_monitor.py | 108 ++++++++---------------- 1 file changed, 37 insertions(+), 71 deletions(-) diff --git a/src/oled_monitor/rascsi_oled_monitor.py b/src/oled_monitor/rascsi_oled_monitor.py index b2e3a639..35dad3db 100755 --- a/src/oled_monitor/rascsi_oled_monitor.py +++ b/src/oled_monitor/rascsi_oled_monitor.py @@ -29,92 +29,57 @@ # THE SOFTWARE. import time import os +import sys import datetime - -#import Adafruit_GPIO.SPI as SPI -import Adafruit_SSD1306 - -from PIL import Image -from PIL import ImageDraw -from PIL import ImageFont - +import board +import busio +import adafruit_ssd1306 +from PIL import Image, ImageDraw, ImageFont import subprocess +WIDTH = 128 +HEIGHT = 32 # Change to 64 if needed +BORDER = 5 + # How long to delay between each update delay_time_ms = 250 -# Raspberry Pi pin configuration: -RST = None # on the PiOLED this pin isnt used -# Note the following are only used with SPI: -DC = 23 -SPI_PORT = 0 -SPI_DEVICE = 0 +# Define the Reset Pin +oled_reset = None -# Beaglebone Black pin configuration: -# RST = 'P9_12' -# Note the following are only used with SPI: -# DC = 'P9_15' -# SPI_PORT = 1 -# SPI_DEVICE = 0 +# init i2c +i2c = board.I2C() # 128x32 display with hardware I2C: -disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST) +oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C, reset=oled_reset) -# 128x64 display with hardware I2C: -# disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST) - -# Note you can change the I2C address by passing an i2c_address parameter like: -# disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, i2c_address=0x3C) - -# Alternatively you can specify an explicit I2C bus number, for example -# with the 128x32 display you would use: -# disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, i2c_bus=2) - -# 128x32 display with hardware SPI: -# disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000)) - -# 128x64 display with hardware SPI: -# disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000)) - -# Alternatively you can specify a software SPI implementation by providing -# digital GPIO pin numbers for all the required display pins. For example -# on a Raspberry Pi with the 128x32 display you might use: -# disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, sclk=18, din=25, cs=22) - -print "Running with the following display:" -print disp -print -print "Will update the OLED display every " + str(delay_time_ms) + "ms (approximately)" - - -# Initialize library. -disp.begin() +print ("Running with the following display:") +print (oled) +print () +print ("Will update the OLED display every " + str(delay_time_ms) + "ms (approximately)") # Clear display. -disp.clear() -disp.display() +oled.fill(0) +oled.show() # Create blank image for drawing. # Make sure to create image with mode '1' for 1-bit color. -width = disp.width -height = disp.height -image = Image.new('1', (width, height)) +image = Image.new("1", (oled.width, oled.height)) # Get drawing object to draw on image. draw = ImageDraw.Draw(image) # Draw a black filled box to clear the image. -draw.rectangle((0,0,width,height), outline=0, fill=0) +draw.rectangle((0,0,WIDTH,HEIGHT), outline=0, fill=0) # Draw some shapes. # First define some constants to allow easy resizing of shapes. padding = -2 top = padding -bottom = height-padding +bottom = HEIGHT-padding # Move left to right keeping track of the current x position for drawing shapes. x = 0 - # Load default font. font = ImageFont.load_default() @@ -125,10 +90,10 @@ font = ImageFont.load_default() while True: # Draw a black filled box to clear the image. - draw.rectangle((0,0,width,height), outline=0, fill=0) + draw.rectangle((0,0,WIDTH,HEIGHT), outline=0, fill=0) cmd = "rasctl -l" - rascsi_list = subprocess.check_output(cmd, shell=True) + rascsi_list = subprocess.check_output(cmd, shell=True).decode(sys.stdout.encoding) y_pos = top # Draw all of the meaningful data to the 'image' @@ -146,19 +111,20 @@ while True: for line in rascsi_list.split('\n'): # Skip empty strings, divider lines and the header line... if (len(line) == 0) or line.startswith("+---") or line.startswith("| ID | UN"): - continue - else: - if line.startswith("| "): - fields = line.split('|') - output = str.strip(fields[1]) + " " + str.strip(fields[3]) + " " + os.path.basename(str.strip(fields[4])) - else: - output = "No image mounted!" - draw.text((x, y_pos), output, font=font, fill=255) - y_pos = y_pos + 8 + continue + else: + if line.startswith("| "): + fields = line.split('|') + output = str.strip(fields[1]) + " " + str.strip(fields[3]) + " " + os.path.basename(str.strip(fields[4])) + else: + output = "No image mounted!" + draw.text((x, y_pos), output, font=font, fill=255) + y_pos += 8 + # If there is still room on the screen, we'll display the time. If there's not room it will just be clipped draw.text((x, y_pos), datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S"), font=font, fill=255) # Display image. - disp.image(image) - disp.display() + oled.image(image) + oled.show() time.sleep(1/delay_time_ms) From f4513ca87edfaec3e75118d03d7fa4e05dae0cdc Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Sat, 6 Mar 2021 16:50:59 -0600 Subject: [PATCH 18/22] Add start script to simplify oled install --- .gitignore | 3 + src/oled_monitor/rascsi_oled_monitor.py | 2 +- src/oled_monitor/requirements.txt | 14 +++++ src/oled_monitor/start.sh | 76 +++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/oled_monitor/requirements.txt create mode 100755 src/oled_monitor/start.sh diff --git a/.gitignore b/.gitignore index 7b05f121..e17ba71f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ core .idea/ .DS_Store *.swp +__pycache__ +src/web/current +src/oled_monitor/current diff --git a/src/oled_monitor/rascsi_oled_monitor.py b/src/oled_monitor/rascsi_oled_monitor.py index 35dad3db..38048815 100755 --- a/src/oled_monitor/rascsi_oled_monitor.py +++ b/src/oled_monitor/rascsi_oled_monitor.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # RaSCSI Updates: # Updates to output rascsi status to an OLED display diff --git a/src/oled_monitor/requirements.txt b/src/oled_monitor/requirements.txt new file mode 100644 index 00000000..eebfd0cd --- /dev/null +++ b/src/oled_monitor/requirements.txt @@ -0,0 +1,14 @@ +Adafruit-Blinka==6.3.2 +adafruit-circuitpython-busdevice==5.0.6 +adafruit-circuitpython-framebuf==1.4.6 +adafruit-circuitpython-ssd1306==2.11.1 +Adafruit-PlatformDetect==3.2.0 +Adafruit-PureIO==1.1.8 +Pillow==8.1.2 +pkg-resources==0.0.0 +pyftdi==0.52.9 +pyserial==3.5 +pyusb==1.1.1 +rpi-ws281x==4.2.5 +RPi.GPIO==0.7.0 +sysv-ipc==1.1.0 diff --git a/src/oled_monitor/start.sh b/src/oled_monitor/start.sh new file mode 100755 index 00000000..f0a37013 --- /dev/null +++ b/src/oled_monitor/start.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash +set -e +# set -x # Uncomment to Debug + +cd $(dirname $0) +# verify packages installed +ERROR=0 +if ! command -v dpkg -l i2c-tools &> /dev/null ; then + echo "i2c-tools could not be found" + echo "Run 'sudo apt install i2c-tools' to fix." + ERROR=1 +fi +if ! command -v python3 &> /dev/null ; then + echo "python3 could not be found" + echo "Run 'sudo apt install python3' to fix." + ERROR=1 +fi +# Dep to build Pillow +if ! dpkg -l python3-dev &> /dev/null; then + echo "python3-dev could not be found" + echo "Run 'sudo apt install python3-dev' to fix." + ERROR=1 +fi +if ! dpkg -l libjpeg-dev &> /dev/null; then + echo "libjpeg-dev could not be found" + echo "Run 'sudo apt install libjpeg-dev' to fix." + ERROR=1 +fi +if ! dpkg -l libpng-dev &> /dev/null; then + echo "libpng-dev could not be found" + echo "Run 'sudo apt install libpng-dev' to fix." + ERROR=1 +fi +# Dep to build Pollow +if ! python3 -m venv --help &> /dev/null ; then + echo "venv could not be found" + echo "Run 'sudo apt install python3-venv' to fix." + ERROR=1 +fi +if [ $ERROR = 1 ] ; then + echo + echo "Fix errors and re-run ./start.sh" + exit 1 +fi + +if ! i2cdetect -y 1 &> /dev/null ; then + echo "i2cdetect -y 1 did not find a screen." + exit 2 +fi +if ! test -e venv; then + echo "Creating python venv for OLED Screen" + python3 -m venv venv + echo "Activating venv" + source venv/bin/activate + echo "Installing requirements.txt" + pip install -r requirements.txt + git rev-parse HEAD > current +fi + +source venv/bin/activate + +# Detect if someone updates - we need to re-run pip install. +if ! test -e current; then + git rev-parse > current +else + if [ "$(cat current)" != "$(git rev-parse HEAD)" ]; then + echo "New version detected, updating requirements.txt" + echo " This may take some time..." + pip install wheel + pip install -r requirements.txt + git rev-parse HEAD > current + fi +fi + +echo "Starting OLED Screen..." +python3 rascsi_oled_monitor.py From cbd7f17508250570dd62f742091ed02082a42ce4 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Sun, 7 Mar 2021 09:52:04 -0600 Subject: [PATCH 19/22] Stay on currently checked out branch for easy intall --- easyinstall.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/easyinstall.sh b/easyinstall.sh index 811adda9..66728bdc 100755 --- a/easyinstall.sh +++ b/easyinstall.sh @@ -24,7 +24,7 @@ VIRTUAL_DRIVER_PATH=/home/pi/images HFS_FORMAT=/usr/bin/hformat HFDISK_BIN=/usr/bin/hfdisk LIDO_DRIVER=~/RASCSI/lido-driver.img - +GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) function initialChecks() { currentUser=$(whoami) @@ -103,10 +103,11 @@ function installRaScsiWebInterface() { } function updateRaScsiGit() { + echo "Updating checked out branch $GIT_BRANCH" cd ~/RASCSI - git fetch + git fetch origin git stash - git rebase origin/master + git rebase origin/$GIT_BRANCH git stash apply } From 1fb0269645feda44d689a597339bef332efd9258 Mon Sep 17 00:00:00 2001 From: PhrAx <68938882+phrax0@users.noreply.github.com> Date: Sun, 7 Mar 2021 17:11:17 -0800 Subject: [PATCH 20/22] Update controllers Includes comment alignment, and added RESERVE(6), RESERVE(10), RELEASE(6) and RELEASE(10) for SCSI, along with RESERVE(16) and RELEASE(17) for SASI. --- src/raspberrypi/controllers/sasidev_ctrl.cpp | 402 ++++++++++--------- src/raspberrypi/controllers/sasidev_ctrl.h | 211 ++++------ src/raspberrypi/controllers/scsidev_ctrl.cpp | 341 ++++++++++------ src/raspberrypi/controllers/scsidev_ctrl.h | 134 +++---- 4 files changed, 567 insertions(+), 521 deletions(-) diff --git a/src/raspberrypi/controllers/sasidev_ctrl.cpp b/src/raspberrypi/controllers/sasidev_ctrl.cpp index 0cd1f420..5e50e67a 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.cpp +++ b/src/raspberrypi/controllers/sasidev_ctrl.cpp @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SASI device controller ] +// [ SASI device controller ] // //--------------------------------------------------------------------------- #include "controllers/sasidev_ctrl.h" @@ -37,10 +37,10 @@ SASIDEV::SASIDEV(Device *dev) { int i; -#ifndef RASCSI + #ifndef RASCSI // Remember host device host = dev; -#endif // RASCSI + #endif // RASCSI // Work initialization ctrl.phase = BUS::busfree; @@ -49,9 +49,9 @@ SASIDEV::SASIDEV(Device *dev) memset(ctrl.cmd, 0x00, sizeof(ctrl.cmd)); ctrl.status = 0x00; ctrl.message = 0x00; -#ifdef RASCSI + #ifdef RASCSI ctrl.execstart = 0; -#endif // RASCSI + #endif // RASCSI ctrl.bufsize = 0x800; ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); memset(ctrl.buffer, 0x00, ctrl.bufsize); @@ -96,9 +96,9 @@ void FASTCALL SASIDEV::Reset() ctrl.phase = BUS::busfree; ctrl.status = 0x00; ctrl.message = 0x00; -#ifdef RASCSI + #ifdef RASCSI ctrl.execstart = 0; -#endif // RASCSI + #endif // RASCSI memset(ctrl.buffer, 0x00, ctrl.bufsize); ctrl.blocks = 0; ctrl.next = 0; @@ -301,9 +301,9 @@ BUS::phase_t FASTCALL SASIDEV::Process() // For the monitor tool, we shouldn't need to reset. We're just logging information // Reset if (ctrl.bus->GetRST()) { -#if defined(DISK_LOG) - Log(Log::Normal, "RESET signal received"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - RESET signal received"); + #endif // DISK_LOG // Reset the controller Reset(); @@ -371,9 +371,9 @@ void FASTCALL SASIDEV::BusFree() // Phase change if (ctrl.phase != BUS::busfree) { -#if defined(DISK_LOG) - Log(Log::Normal, "Bus free phase"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Bus free phase"); + #endif // DISK_LOG // Phase Setting ctrl.phase = BUS::busfree; @@ -421,10 +421,9 @@ void FASTCALL SASIDEV::Selection() return; } -#if defined(DISK_LOG) - Log(Log::Normal, - "Selection Phase ID=%d (with device)", ctrl.id); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal,"SASI - Selection Phase ID=%d (with device)", ctrl.id); + #endif // DISK_LOG // Phase change ctrl.phase = BUS::selection; @@ -447,19 +446,19 @@ void FASTCALL SASIDEV::Selection() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::Command() { -#ifdef RASCSI + #ifdef RASCSI int count; int i; -#endif // RASCSI + #endif // RASCSI ASSERT(this); // Phase change if (ctrl.phase != BUS::command) { -#if defined(DISK_LOG) - Log(Log::Normal, "Command Phase"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Command Phase"); + #endif // DISK_LOG // Phase Setting ctrl.phase = BUS::command; @@ -474,7 +473,7 @@ void FASTCALL SASIDEV::Command() ctrl.length = 6; ctrl.blocks = 1; -#ifdef RASCSI + #ifdef RASCSI // Command reception handshake (10 bytes are automatically received at the first command) count = ctrl.bus->CommandHandShake(ctrl.buffer); @@ -506,13 +505,13 @@ void FASTCALL SASIDEV::Command() // Execution Phase Execute(); -#else + #else // Request the command ctrl.bus->SetREQ(TRUE); return; -#endif // RASCSI + #endif // RASCSI } -#ifndef RASCSI + #ifndef RASCSI // Requesting if (ctrl.bus->GetREQ()) { // Sent by the initiator @@ -525,7 +524,7 @@ void FASTCALL SASIDEV::Command() ReceiveNext(); } } -#endif // RASCSI + #endif // RASCSI } //--------------------------------------------------------------------------- @@ -537,9 +536,9 @@ void FASTCALL SASIDEV::Execute() { ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "Execution Phase Command %02X", ctrl.cmd[0]); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Execution Phase Command %02X", ctrl.cmd[0]); + #endif // DISK_LOG // Phase Setting ctrl.phase = BUS::execute; @@ -547,9 +546,9 @@ void FASTCALL SASIDEV::Execute() // Initialization for data transfer ctrl.offset = 0; ctrl.blocks = 1; -#ifdef RASCSI + #ifdef RASCSI ctrl.execstart = SysTimer::GetTimerLow(); -#endif // RASCSI + #endif // RASCSI // Process by command switch (ctrl.cmd[0]) { @@ -603,14 +602,25 @@ void FASTCALL SASIDEV::Execute() CmdAssign(); return; + // RESERVE UNIT(16) + case 0x16: + CmdReserveUnit(); + return; + + // RELEASE UNIT(17) + case 0x17: + CmdReleaseUnit(); + return; + // SPECIFY(SASIのみ) case 0xc2: CmdSpecify(); return; + } // Unsupported command - Log(Log::Warning, "Unsupported command $%02X", ctrl.cmd[0]); + Log(Log::Warning, "SASI - Unsupported command $%02X", ctrl.cmd[0]); CmdInvalid(); } @@ -621,17 +631,17 @@ void FASTCALL SASIDEV::Execute() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::Status() { -#ifdef RASCSI + #ifdef RASCSI DWORD min_exec_time; DWORD time; -#endif // RASCSI + #endif // RASCSI ASSERT(this); // Phase change if (ctrl.phase != BUS::status) { -#ifdef RASCSI + #ifdef RASCSI // Minimum execution time if (ctrl.execstart > 0) { min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi; @@ -643,11 +653,11 @@ void FASTCALL SASIDEV::Status() } else { SysTimer::SleepUsec(5); } -#endif // RASCSI + #endif // RASCSI -#if defined(DISK_LOG) - Log(Log::Normal, "Status phase"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Status phase"); + #endif // DISK_LOG // Phase Setting ctrl.phase = BUS::status; @@ -663,22 +673,22 @@ void FASTCALL SASIDEV::Status() ctrl.blocks = 1; ctrl.buffer[0] = (BYTE)ctrl.status; -#ifndef RASCSI + #ifndef RASCSI // Request status ctrl.bus->SetDAT(ctrl.buffer[0]); ctrl.bus->SetREQ(TRUE); -#if defined(DISK_LOG) - Log(Log::Normal, "Status Phase $%02X", ctrl.status); -#endif // DISK_LOG -#endif // RASCSI + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Status Phase $%02X", ctrl.status); + #endif // DISK_LOG + #endif // RASCSI return; } -#ifdef RASCSI + #ifdef RASCSI // Send Send(); -#else + #else // Requesting if (ctrl.bus->GetREQ()) { // Initiator received @@ -691,7 +701,7 @@ void FASTCALL SASIDEV::Status() Send(); } } -#endif // RASCSI + #endif // RASCSI } //--------------------------------------------------------------------------- @@ -706,9 +716,9 @@ void FASTCALL SASIDEV::MsgIn() // Phase change if (ctrl.phase != BUS::msgin) { -#if defined(DISK_LOG) - Log(Log::Normal, "Message in phase"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Message in phase"); + #endif // DISK_LOG // Phase Setting ctrl.phase = BUS::msgin; @@ -723,22 +733,22 @@ void FASTCALL SASIDEV::MsgIn() ASSERT(ctrl.blocks > 0); ctrl.offset = 0; -#ifndef RASCSI + #ifndef RASCSI // Request message ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); ctrl.bus->SetREQ(TRUE); -#if defined(DISK_LOG) - Log(Log::Normal, "Message in phase $%02X", ctrl.buffer[ctrl.offset]); -#endif // DISK_LOG -#endif // RASCSI + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Message in phase $%02X", ctrl.buffer[ctrl.offset]); + #endif // DISK_LOG + #endif // RASCSI return; } -#ifdef RASCSI + #ifdef RASCSI //Send Send(); -#else + #else // Requesting if (ctrl.bus->GetREQ()) { // Initator received @@ -751,7 +761,7 @@ void FASTCALL SASIDEV::MsgIn() Send(); } } -#endif // RASCSI + #endif // RASCSI } //--------------------------------------------------------------------------- @@ -761,10 +771,10 @@ void FASTCALL SASIDEV::MsgIn() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::DataIn() { -#ifdef RASCSI + #ifdef RASCSI DWORD min_exec_time; DWORD time; -#endif // RASCSI + #endif // RASCSI ASSERT(this); ASSERT(ctrl.length >= 0); @@ -772,7 +782,7 @@ void FASTCALL SASIDEV::DataIn() // Phase change if (ctrl.phase != BUS::datain) { -#ifdef RASCSI + #ifdef RASCSI // Minimum execution time if (ctrl.execstart > 0) { min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi; @@ -782,7 +792,7 @@ void FASTCALL SASIDEV::DataIn() } ctrl.execstart = 0; } -#endif // RASCSI + #endif // RASCSI // If the length is 0, go to the status phase if (ctrl.length == 0) { @@ -790,9 +800,9 @@ void FASTCALL SASIDEV::DataIn() return; } -#if defined(DISK_LOG) - Log(Log::Normal, "Data-in Phase"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Data-in Phase"); + #endif // DISK_LOG // Phase Setting ctrl.phase = BUS::datain; @@ -807,20 +817,20 @@ void FASTCALL SASIDEV::DataIn() ASSERT(ctrl.blocks > 0); ctrl.offset = 0; -#ifndef RASCSI + #ifndef RASCSI // Assert the DAT signal ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); // Request data ctrl.bus->SetREQ(TRUE); -#endif // RASCSI + #endif // RASCSI return; } -#ifdef RASCSI + #ifdef RASCSI // Send Send(); -#else + #else // Requesting if (ctrl.bus->GetREQ()) { // Initator received @@ -833,7 +843,7 @@ void FASTCALL SASIDEV::DataIn() Send(); } } -#endif // RASCSI + #endif // RASCSI } //--------------------------------------------------------------------------- @@ -843,10 +853,10 @@ void FASTCALL SASIDEV::DataIn() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::DataOut() { -#ifdef RASCSI + #ifdef RASCSI DWORD min_exec_time; DWORD time; -#endif // RASCSI + #endif // RASCSI ASSERT(this); ASSERT(ctrl.length >= 0); @@ -854,7 +864,7 @@ void FASTCALL SASIDEV::DataOut() // Phase change if (ctrl.phase != BUS::dataout) { -#ifdef RASCSI + #ifdef RASCSI // Minimum execution time if (ctrl.execstart > 0) { min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi; @@ -864,7 +874,7 @@ void FASTCALL SASIDEV::DataOut() } ctrl.execstart = 0; } -#endif // RASCSI + #endif // RASCSI // If the length is 0, go to the status phase if (ctrl.length == 0) { @@ -872,9 +882,9 @@ void FASTCALL SASIDEV::DataOut() return; } -#if defined(DISK_LOG) - Log(Log::Normal, "Data out phase"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Data out phase"); + #endif // DISK_LOG // Phase Setting ctrl.phase = BUS::dataout; @@ -889,17 +899,17 @@ void FASTCALL SASIDEV::DataOut() ASSERT(ctrl.blocks > 0); ctrl.offset = 0; -#ifndef RASCSI + #ifndef RASCSI // Request data ctrl.bus->SetREQ(TRUE); -#endif // RASCSI + #endif // RASCSI return; } -#ifdef RASCSI + #ifdef RASCSI // Receive Receive(); -#else + #else // Requesting if (ctrl.bus->GetREQ()) { // Sent by the initiator @@ -912,7 +922,7 @@ void FASTCALL SASIDEV::DataOut() ReceiveNext(); } } -#endif // RASCSI + #endif // RASCSI } //--------------------------------------------------------------------------- @@ -945,9 +955,9 @@ void FASTCALL SASIDEV::Error() return; } -#if defined(DISK_LOG) - Log(Log::Warning, "Error occured (going to status phase)"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Warning, "SASI - Error occured (going to status phase)"); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -971,9 +981,9 @@ void FASTCALL SASIDEV::CmdTestUnitReady() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "TEST UNIT READY Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - TEST UNIT READY Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1006,9 +1016,9 @@ void FASTCALL SASIDEV::CmdRezero() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "REZERO UNIT Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - REZERO UNIT Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1040,9 +1050,9 @@ void FASTCALL SASIDEV::CmdRequestSense() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "REQUEST SENSE Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - REQUEST SENSE Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1055,9 +1065,9 @@ void FASTCALL SASIDEV::CmdRequestSense() ctrl.length = ctrl.unit[lun]->RequestSense(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length > 0); -#if defined(DISK_LOG) - Log(Log::Normal, "Sense key $%02X", ctrl.buffer[2]); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Sense key $%02X", ctrl.buffer[2]); + #endif // DISK_LOG // Read phase DataIn(); @@ -1075,9 +1085,9 @@ void FASTCALL SASIDEV::CmdFormat() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "FORMAT UNIT Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - FORMAT UNIT Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1110,9 +1120,9 @@ void FASTCALL SASIDEV::CmdReassign() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "REASSIGN BLOCKS Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - REASSIGN BLOCKS Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1133,6 +1143,42 @@ void FASTCALL SASIDEV::CmdReassign() Status(); } +// The following commands RESERVE UNIT and RELEASE UNIT are not properly implemented. +// These commands are used in multi-initator environments which this project is not targeted at. +// For now, we simply reply with an OK. -phrax 2021-03-06 + +//--------------------------------------------------------------------------- +// +// RESERVE UNIT(16) +// +//--------------------------------------------------------------------------- +void FASTCALL SASIDEV::CmdReserveUnit() +{ + ASSERT(this); + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - RESERVE UNIT Command"); + #endif // DISK_LOG + + // status phase + Status(); +} + +//--------------------------------------------------------------------------- +// +// RELEASE UNIT(17) +// +//--------------------------------------------------------------------------- +void FASTCALL SASIDEV::CmdReleaseUnit() +{ + ASSERT(this); + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - RELEASE UNIT Command"); + #endif // DISK_LOG + + // status phase + Status(); +} + //--------------------------------------------------------------------------- // // READ(6) @@ -1163,10 +1209,9 @@ void FASTCALL SASIDEV::CmdRead6() ctrl.blocks = 0x100; } -#if defined(DISK_LOG) - Log(Log::Normal, - "READ(6) command record=%06X blocks=%d", record, ctrl.blocks); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal,"SASI - READ(6) command record=%06X blocks=%d", record, ctrl.blocks); + #endif // DISK_LOG // Command processing on drive ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record); @@ -1213,10 +1258,9 @@ void FASTCALL SASIDEV::CmdWrite6() ctrl.blocks = 0x100; } -#if defined(DISK_LOG) - Log(Log::Normal, - "WRITE(6) command record=%06X blocks=%d", record, ctrl.blocks); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal,"SASI - WRITE(6) command record=%06X blocks=%d", record, ctrl.blocks); + #endif // DISK_LOG // Command processing on drive ctrl.length = ctrl.unit[lun]->WriteCheck(record); @@ -1245,9 +1289,9 @@ void FASTCALL SASIDEV::CmdSeek6() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "SEEK(6) Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - SEEK(6) Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1280,9 +1324,9 @@ void FASTCALL SASIDEV::CmdAssign() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "ASSIGN Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - ASSIGN Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1318,9 +1362,9 @@ void FASTCALL SASIDEV::CmdSpecify() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "SPECIFY Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - SPECIFY Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1355,9 +1399,9 @@ void FASTCALL SASIDEV::CmdInvalid() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "Command not supported"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Command not supported"); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1383,16 +1427,16 @@ void FASTCALL SASIDEV::CmdInvalid() //--------------------------------------------------------------------------- void FASTCALL SASIDEV::Send() { -#ifdef RASCSI + #ifdef RASCSI int len; -#endif // RASCSI + #endif // RASCSI BOOL result; ASSERT(this); ASSERT(!ctrl.bus->GetREQ()); ASSERT(ctrl.bus->GetIO()); -#ifdef RASCSI + #ifdef RASCSI // Check that the length isn't 0 if (ctrl.length != 0) { len = ctrl.bus->SendHandShake( @@ -1409,7 +1453,7 @@ void FASTCALL SASIDEV::Send() ctrl.length = 0; return; } -#else + #else // Offset and Length ASSERT(ctrl.length >= 1); ctrl.offset++; @@ -1422,7 +1466,7 @@ void FASTCALL SASIDEV::Send() ctrl.bus->SetREQ(TRUE); return; } -#endif // RASCSI + #endif // RASCSI // Remove block and initialize the result ctrl.blocks--; @@ -1435,9 +1479,9 @@ void FASTCALL SASIDEV::Send() result = XferIn(ctrl.buffer); //** printf("xfer in: %d \n",result); -#ifndef RASCSI + #ifndef RASCSI ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); -#endif // RASCSI + #endif // RASCSI } } @@ -1451,10 +1495,10 @@ void FASTCALL SASIDEV::Send() if (ctrl.blocks != 0){ ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); -#ifndef RASCSI + #ifndef RASCSI // Signal line operated by the target ctrl.bus->SetREQ(TRUE); -#endif // RASCSI + #endif // RASCSI return; } @@ -1538,9 +1582,9 @@ void FASTCALL SASIDEV::Receive() // Command phase case BUS::command: ctrl.cmd[ctrl.offset] = data; -#if defined(DISK_LOG) - Log(Log::Normal, "Command phase $%02X", data); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SASI - Command phase $%02X", data); + #endif // DISK_LOG // Set the length again with the first data (offset 0) if (ctrl.offset == 0) { @@ -1580,9 +1624,9 @@ void FASTCALL SASIDEV::Receive() void FASTCALL SASIDEV::ReceiveNext() #endif // RASCSI { -#ifdef RASCSI + #ifdef RASCSI int len; -#endif // RASCSI + #endif // RASCSI BOOL result; ASSERT(this); @@ -1591,7 +1635,7 @@ void FASTCALL SASIDEV::ReceiveNext() ASSERT(!ctrl.bus->GetREQ()); ASSERT(!ctrl.bus->GetIO()); -#ifdef RASCSI + #ifdef RASCSI // Length != 0 if received if (ctrl.length != 0) { // Receive @@ -1609,7 +1653,7 @@ void FASTCALL SASIDEV::ReceiveNext() ctrl.length = 0; return; } -#else + #else // Offset and Length ASSERT(ctrl.length >= 1); ctrl.offset++; @@ -1621,7 +1665,7 @@ void FASTCALL SASIDEV::ReceiveNext() ctrl.bus->SetREQ(TRUE); return; } -#endif // RASCSI + #endif // RASCSI // Remove the control block and initialize the result ctrl.blocks--; @@ -1648,22 +1692,22 @@ void FASTCALL SASIDEV::ReceiveNext() if (ctrl.blocks != 0){ ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); -#ifndef RASCSI + #ifndef RASCSI // Signal line operated by the target ctrl.bus->SetREQ(TRUE); -#endif // RASCSI + #endif // RASCSI return; } // Move to the next phase switch (ctrl.phase) { -#ifndef RASCSI + #ifndef RASCSI // Command phase case BUS::command: // Execution Phase Execute(); break; -#endif // RASCSI + #endif // RASCSI // Data out phase case BUS::dataout: @@ -1856,7 +1900,7 @@ void FASTCALL SASIDEV::FlushUnit() // Debug code related to Issue #2 on github, where we get an unhandled Model select when // the mac is rebooted // https://github.com/akuker/RASCSI/issues/2 - Log(Log::Warning, "Received \'Mode Select\'\n"); + Log(Log::Warning, "SASI - Received \'Mode Select\'\n"); Log(Log::Warning, " Operation Code: [%02X]\n", ctrl.cmd[0]); Log(Log::Warning, " Logical Unit %01X, PF %01X, SP %01X [%02X]\n", ctrl.cmd[1] >> 5, 1 & (ctrl.cmd[1] >> 4), ctrl.cmd[1] & 1, ctrl.cmd[1]); Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[2]); @@ -1868,13 +1912,13 @@ void FASTCALL SASIDEV::FlushUnit() if (!ctrl.unit[lun]->ModeSelect( ctrl.cmd, ctrl.buffer, ctrl.offset)) { // MODE SELECT failed - Log(Log::Warning, "Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]); + Log(Log::Warning, "SASI - Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]); return; } break; default: - Log(Log::Warning, "Received an invalid flush command %02X!!!!!\n",ctrl.cmd[0]); + Log(Log::Warning, "SASI - Received an invalid flush command %02X!!!!!\n",ctrl.cmd[0]); ASSERT(FALSE); break; } @@ -1938,13 +1982,13 @@ void SASIDEV::GetPhaseStr(char *str) //--------------------------------------------------------------------------- void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...) { -#if !defined(BAREMETAL) -#ifdef DISK_LOG + #if !defined(BAREMETAL) + #ifdef DISK_LOG char buffer[0x200]; char buffer2[0x250]; char buffer3[0x250]; char phase_str[20]; -#endif + #endif va_list args; va_start(args, format); @@ -1953,15 +1997,15 @@ void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...) return; } -#ifdef RASCSI -#ifndef DISK_LOG + #ifdef RASCSI + #ifndef DISK_LOG if (level == Log::Warning) { return; } -#endif // DISK_LOG -#endif // RASCSI + #endif // DISK_LOG + #endif // RASCSI -#ifdef DISK_LOG + #ifdef DISK_LOG // format vsprintf(buffer, format, args); @@ -1970,30 +2014,28 @@ void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...) // Add the date/timestamp // current date/time based on current system - time_t now = time(0); - // convert now to string form - char* dt = ctime(&now); + time_t now = time(0); + // convert now to string form + char* dt = ctime(&now); + strcpy(buffer2, "["); + strcat(buffer2, dt); + // Get rid of the carriage return + buffer2[strlen(buffer2)-1] = '\0'; + strcat(buffer2, "] "); - strcpy(buffer2, "["); - strcat(buffer2, dt); - // Get rid of the carriage return - buffer2[strlen(buffer2)-1] = '\0'; - strcat(buffer2, "] "); + // Get the phase + this->GetPhaseStr(phase_str); + sprintf(buffer3, "[%d][%s] ", this->GetID(), phase_str); + strcat(buffer2,buffer3); + strcat(buffer2, buffer); - // Get the phase - this->GetPhaseStr(phase_str); - sprintf(buffer3, "[%d][%s] ", this->GetID(), phase_str); - strcat(buffer2,buffer3); - strcat(buffer2, buffer); - - - // Log output -#ifdef RASCSI + // Log output + #ifdef RASCSI printf("%s\n", buffer2); -#else + #else host->GetVM()->GetLog()->Format(level, host, buffer); -#endif // RASCSI -#endif // BAREMETAL -#endif // DISK_LOG + #endif // RASCSI + #endif // BAREMETAL + #endif // DISK_LOG } diff --git a/src/raspberrypi/controllers/sasidev_ctrl.h b/src/raspberrypi/controllers/sasidev_ctrl.h index fc8ec2d0..120f050f 100644 --- a/src/raspberrypi/controllers/sasidev_ctrl.h +++ b/src/raspberrypi/controllers/sasidev_ctrl.h @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SASI device controller ] +// [ SASI device controller ] // //--------------------------------------------------------------------------- #pragma once @@ -31,181 +31,140 @@ class SASIDEV { public: - // Maximum number of logical units enum { - UnitMax = 8 + UnitMax = 8 // Maximum number of logical units }; -#ifdef RASCSI + #ifdef RASCSI // For timing adjustments - enum { + enum { min_exec_time_sasi = 100, // SASI BOOT/FORMAT 30:NG 35:OK min_exec_time_scsi = 50 }; -#endif // RASCSI + #endif // RASCSI // Internal data definition typedef struct { // 全般 BUS::phase_t phase; // Transition phase - int id; // Controller ID (0-7) - BUS *bus; // Bus + int id; // Controller ID (0-7) + BUS *bus; // Bus // commands DWORD cmd[10]; // Command data DWORD status; // Status data DWORD message; // Message data -#ifdef RASCSI + #ifdef RASCSI // Run DWORD execstart; // Execution start time -#endif // RASCSI + #endif // RASCSI // Transfer BYTE *buffer; // Transfer data buffer int bufsize; // Transfer data buffer size DWORD blocks; // Number of transfer block - DWORD next; // Next record + DWORD next; // Next record DWORD offset; // Transfer offset DWORD length; // Transfer remaining length // Logical unit - Disk *unit[UnitMax]; - // Logical Unit + Disk *unit[UnitMax]; // Logical Unit } ctrl_t; public: // Basic Functions -#ifdef RASCSI + #ifdef RASCSI SASIDEV(); -#else - SASIDEV(Device *dev); -#endif //RASCSI + #else - // Constructor - virtual ~SASIDEV(); - // Destructor - virtual void FASTCALL Reset(); - // Device Reset -#ifndef RASCSI - virtual BOOL FASTCALL Save(Fileio *fio, int ver); - // Save - virtual BOOL FASTCALL Load(Fileio *fio, int ver); - // Load -#endif //RASCSI + SASIDEV(Device *dev); // Constructor + + #endif //RASCSI + virtual ~SASIDEV(); // Destructor + virtual void FASTCALL Reset(); // Device Reset + + #ifndef RASCSI + virtual BOOL FASTCALL Save(Fileio *fio, int ver); // Save + virtual BOOL FASTCALL Load(Fileio *fio, int ver); // Load + #endif //RASCSI // External API - virtual BUS::phase_t FASTCALL Process(); - // Run + virtual BUS::phase_t FASTCALL Process(); // Run // Connect - void FASTCALL Connect(int id, BUS *sbus); - // Controller connection - Disk* FASTCALL GetUnit(int no); - // Get logical unit - void FASTCALL SetUnit(int no, Disk *dev); - // Logical unit setting - BOOL FASTCALL HasUnit(); - // Has a valid logical unit + void FASTCALL Connect(int id, BUS *sbus); // Controller connection + Disk* FASTCALL GetUnit(int no); // Get logical unit + void FASTCALL SetUnit(int no, Disk *dev); // Logical unit setting + BOOL FASTCALL HasUnit(); // Has a valid logical unit // Other - BUS::phase_t FASTCALL GetPhase() {return ctrl.phase;} - // Get the phase -#ifdef DISK_LOG - // Function to get the current phase as a String. - void FASTCALL GetPhaseStr(char *str); -#endif + BUS::phase_t FASTCALL GetPhase() {return ctrl.phase;} // Get the phase + #ifdef DISK_LOG - int FASTCALL GetID() {return ctrl.id;} - // Get the ID - void FASTCALL GetCTRL(ctrl_t *buffer); - // Get the internal information - ctrl_t* FASTCALL GetWorkAddr() { return &ctrl; } - // Get the internal information address - virtual BOOL FASTCALL IsSASI() const {return TRUE;} - // SASI Check - virtual BOOL FASTCALL IsSCSI() const {return FALSE;} - // SCSI check - Disk* FASTCALL GetBusyUnit(); - // Get the busy unit + // Function to get the current phase as a String. + void FASTCALL GetPhaseStr(char *str); + #endif + + int FASTCALL GetID() {return ctrl.id;} // Get the ID + void FASTCALL GetCTRL(ctrl_t *buffer); // Get the internal information + ctrl_t* FASTCALL GetWorkAddr() { return &ctrl; } // Get the internal information address + virtual BOOL FASTCALL IsSASI() const {return TRUE;} // SASI Check + virtual BOOL FASTCALL IsSCSI() const {return FALSE;} // SCSI check + Disk* FASTCALL GetBusyUnit(); // Get the busy unit protected: // Phase processing - virtual void FASTCALL BusFree(); - // Bus free phase - virtual void FASTCALL Selection(); - // Selection phase - virtual void FASTCALL Command(); - // Command phase - virtual void FASTCALL Execute(); - // Execution phase - void FASTCALL Status(); - // Status phase - void FASTCALL MsgIn(); - // Message in phase - void FASTCALL DataIn(); - // Data in phase - void FASTCALL DataOut(); - // Data out phase - virtual void FASTCALL Error(); - // Common error handling + virtual void FASTCALL BusFree(); // Bus free phase + virtual void FASTCALL Selection(); // Selection phase + virtual void FASTCALL Command(); // Command phase + virtual void FASTCALL Execute(); // Execution phase + void FASTCALL Status(); // Status phase + void FASTCALL MsgIn(); // Message in phase + void FASTCALL DataIn(); // Data in phase + void FASTCALL DataOut(); // Data out phase + virtual void FASTCALL Error(); // Common error handling // commands - void FASTCALL CmdTestUnitReady(); - // TEST UNIT READY command - void FASTCALL CmdRezero(); - // REZERO UNIT command - void FASTCALL CmdRequestSense(); - // REQUEST SENSE command - void FASTCALL CmdFormat(); - // FORMAT command - void FASTCALL CmdReassign(); - // REASSIGN BLOCKS command - void FASTCALL CmdRead6(); - // READ(6) command - void FASTCALL CmdWrite6(); - // WRITE(6) command - void FASTCALL CmdSeek6(); - // SEEK(6) command - void FASTCALL CmdAssign(); - // ASSIGN command - void FASTCALL CmdSpecify(); - // SPECIFY command - void FASTCALL CmdInvalid(); - // Unsupported command + void FASTCALL CmdTestUnitReady(); // TEST UNIT READY command + void FASTCALL CmdRezero(); // REZERO UNIT command + void FASTCALL CmdRequestSense(); // REQUEST SENSE command + void FASTCALL CmdFormat(); // FORMAT command + void FASTCALL CmdReassign(); // REASSIGN BLOCKS command + void FASTCALL CmdReserveUnit(); // RESERVE UNIT command + void FASTCALL CmdReleaseUnit(); // RELEASE UNIT command + void FASTCALL CmdRead6(); // READ(6) command + void FASTCALL CmdWrite6(); // WRITE(6) command + void FASTCALL CmdSeek6(); // SEEK(6) command + void FASTCALL CmdAssign(); // ASSIGN command + void FASTCALL CmdSpecify(); // SPECIFY command + void FASTCALL CmdInvalid(); // Unsupported command // データ転送 - virtual void FASTCALL Send(); - // Send data -#ifndef RASCSI - virtual void FASTCALL SendNext(); - // Continue sending data -#endif // RASCSI - virtual void FASTCALL Receive(); - // Receive data -#ifndef RASCSI - virtual void FASTCALL ReceiveNext(); - // Continue receiving data -#endif // RASCSI - BOOL FASTCALL XferIn(BYTE* buf); - // Data transfer IN - BOOL FASTCALL XferOut(BOOL cont); - // Data transfer OUT + virtual void FASTCALL Send(); // Send data + + #ifndef RASCSI + virtual void FASTCALL SendNext(); // Continue sending data + #endif // RASCSI + + virtual void FASTCALL Receive(); // Receive data + + #ifndef RASCSI + virtual void FASTCALL ReceiveNext(); // Continue receiving data + #endif // RASCSI + + BOOL FASTCALL XferIn(BYTE* buf); // Data transfer IN + BOOL FASTCALL XferOut(BOOL cont); // Data transfer OUT // Special operations - void FASTCALL FlushUnit(); - // Flush the logical unit + void FASTCALL FlushUnit(); // Flush the logical unit // Log - void FASTCALL Log(Log::loglevel level, const char *format, ...); - // Log output + void FASTCALL Log(Log::loglevel level, const char *format, ...); // Log output protected: -#ifndef RASCSI - Device *host; - // Host device -#endif // RASCSI - - ctrl_t ctrl; - // Internal data + #ifndef RASCSI + Device *host; // Host device + #endif // RASCSI + ctrl_t ctrl; // Internal data }; diff --git a/src/raspberrypi/controllers/scsidev_ctrl.cpp b/src/raspberrypi/controllers/scsidev_ctrl.cpp index a496eeb4..50a0e2ea 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.cpp +++ b/src/raspberrypi/controllers/scsidev_ctrl.cpp @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI device controller ] +// [ SCSI device controller ] // //--------------------------------------------------------------------------- #include "controllers/scsidev_ctrl.h" @@ -81,9 +81,9 @@ BUS::phase_t FASTCALL SCSIDEV::Process() // Reset if (ctrl.bus->GetRST()) { -#if defined(DISK_LOG) - Log(Log::Normal, "RESET信号受信"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - RESET信号受信"); + #endif // DISK_LOG // Reset the controller Reset(); @@ -162,9 +162,9 @@ void FASTCALL SCSIDEV::BusFree() // Phase change if (ctrl.phase != BUS::busfree) { -#if defined(DISK_LOG) - Log(Log::Normal, "Bus free phase"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - Bus free phase"); + #endif // DISK_LOG // Phase setting ctrl.phase = BUS::busfree; @@ -215,10 +215,9 @@ void FASTCALL SCSIDEV::Selection() return; } -#if defined(DISK_LOG) - Log(Log::Normal, - "Selection Phase ID=%d (with device)", ctrl.id); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal,"SCSI - Selection Phase ID=%d (with device)", ctrl.id); + #endif // DISK_LOG // Phase setting ctrl.phase = BUS::selection; @@ -248,9 +247,9 @@ void FASTCALL SCSIDEV::Execute() { ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "Execution phase command $%02X", ctrl.cmd[0]); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - Execution phase command $%02X", ctrl.cmd[0]); + #endif // DISK_LOG // Phase Setting ctrl.phase = BUS::execute; @@ -258,9 +257,9 @@ void FASTCALL SCSIDEV::Execute() // Initialization for data transfer ctrl.offset = 0; ctrl.blocks = 1; -#ifdef RASCSI + #ifdef RASCSI ctrl.execstart = SysTimer::GetTimerLow(); -#endif // RASCSI + #endif // RASCSI // Process by command switch (ctrl.cmd[0]) { @@ -314,6 +313,26 @@ void FASTCALL SCSIDEV::Execute() CmdModeSelect(); return; + // RESERVE(6) + case 0x16: + CmdReserve6(); + return; + + // RESERVE(10) + case 0x56: + CmdReserve10(); + return; + + // RELEASE(6) + case 0x17: + CmdRelease6(); + return; + + // RELEASE(10) + case 0x57: + CmdRelease10(); + return; + // MDOE SENSE case 0x1a: CmdModeSense(); @@ -412,7 +431,7 @@ void FASTCALL SCSIDEV::Execute() } // No other support - Log(Log::Normal, "Unsupported command received: $%02X", ctrl.cmd[0]); + Log(Log::Normal, "SCSI - Unsupported command received: $%02X", ctrl.cmd[0]); CmdInvalid(); } @@ -428,12 +447,11 @@ void FASTCALL SCSIDEV::MsgOut() // Phase change if (ctrl.phase != BUS::msgout) { -#if defined(DISK_LOG) - Log(Log::Normal, "Message Out Phase"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - Message Out Phase"); // Message out phase after selection + #endif // DISK_LOG - // Message out phase after selection - // process the IDENTIFY message + // process the IDENTIFY message if (ctrl.phase == BUS::selection) { scsi.atnmsg = TRUE; scsi.msc = 0; @@ -453,17 +471,18 @@ void FASTCALL SCSIDEV::MsgOut() ctrl.length = 1; ctrl.blocks = 1; -#ifndef RASCSI + #ifndef RASCSI // Request message ctrl.bus->SetREQ(TRUE); -#endif // RASCSI + #endif // RASCSI return; } -#ifdef RASCSI + #ifdef RASCSI // Receive Receive(); -#else + #else + // Requesting if (ctrl.bus->GetREQ()) { // Sent by the initiator @@ -476,7 +495,7 @@ void FASTCALL SCSIDEV::MsgOut() ReceiveNext(); } } -#endif // RASCSI + #endif // RASCSI } //--------------------------------------------------------------------------- @@ -507,9 +526,9 @@ void FASTCALL SCSIDEV::Error() return; } -#if defined(DISK_LOG) - Log(Log::Normal, "Error (to status phase)"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - Error (to status phase)"); + #endif // DISK_LOG // Set status and message(CHECK CONDITION) ctrl.status = 0x02; @@ -539,9 +558,9 @@ void FASTCALL SCSIDEV::CmdInquiry() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "INQUIRY Command"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - INQUIRY Command"); + #endif // DISK_LOG // Find a valid unit disk = NULL; @@ -588,9 +607,9 @@ void FASTCALL SCSIDEV::CmdModeSelect() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SELECT Command"); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - MODE SELECT Command"); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -611,6 +630,75 @@ void FASTCALL SCSIDEV::CmdModeSelect() DataOut(); } +// The following commands RESERVE(6), RESERVE(10), RELEASE(6) and RELEASE(10) +// are not properly implemented. These commands are used in multi-initator environments +// which this project is not targeted at. For now, we simply reply with an OK. +// -phrax 2021-03-06 + +//--------------------------------------------------------------------------- +// +// RESERVE(6) +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::CmdReserve6() +{ + ASSERT(this); + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - RESERVE(6) Command"); + #endif // DISK_LOG + + // status phase + Status(); +} + +//--------------------------------------------------------------------------- +// +// RESERVE(10) +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::CmdReserve10() +{ + ASSERT(this); + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - RESERVE(10) Command"); + #endif // DISK_LOG + + // status phase + Status(); +} + +//--------------------------------------------------------------------------- +// +// RELEASE(6) +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::CmdRelease6() +{ + ASSERT(this); + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - RELEASE(6) Command"); + #endif // DISK_LOG + + // status phase + Status(); +} + +//--------------------------------------------------------------------------- +// +// RELEASE(10) +// +//--------------------------------------------------------------------------- +void FASTCALL SCSIDEV::CmdRelease10() +{ + ASSERT(this); + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - RELEASE(10) Command"); + #endif // DISK_LOG + + // status phase + Status(); +} + //--------------------------------------------------------------------------- // // MODE SENSE @@ -622,9 +710,9 @@ void FASTCALL SCSIDEV::CmdModeSense() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SENSE Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - MODE SENSE Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -637,8 +725,7 @@ void FASTCALL SCSIDEV::CmdModeSense() ctrl.length = ctrl.unit[lun]->ModeSense(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length >= 0); if (ctrl.length == 0) { - Log(Log::Warning, - "Not supported MODE SENSE page $%02X", ctrl.cmd[2]); + Log(Log::Warning,"SCSI - Not supported MODE SENSE page $%02X", ctrl.cmd[2]); // Failure (Error) Error(); @@ -661,9 +748,9 @@ void FASTCALL SCSIDEV::CmdStartStop() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "START STOP UNIT Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - START STOP UNIT Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -696,9 +783,9 @@ void FASTCALL SCSIDEV::CmdSendDiag() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "SEND DIAGNOSTIC Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - SEND DIAGNOSTIC Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -731,9 +818,9 @@ void FASTCALL SCSIDEV::CmdRemoval() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "PREVENT/ALLOW MEDIUM REMOVAL Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - PREVENT/ALLOW MEDIUM REMOVAL Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -766,9 +853,9 @@ void FASTCALL SCSIDEV::CmdReadCapacity() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "READ CAPACITY Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - READ CAPACITY Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -829,9 +916,9 @@ void FASTCALL SCSIDEV::CmdRead10() ctrl.blocks <<= 8; ctrl.blocks |= ctrl.cmd[8]; -#if defined(DISK_LOG) - Log(Log::Normal, "READ(10) command record=%08X block=%d", record, ctrl.blocks); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - READ(10) command record=%08X block=%d", record, ctrl.blocks); + #endif // DISK_LOG // Do not process 0 blocks if (ctrl.blocks == 0) { @@ -891,10 +978,9 @@ void FASTCALL SCSIDEV::CmdWrite10() ctrl.blocks <<= 8; ctrl.blocks |= ctrl.cmd[8]; -#if defined(DISK_LOG) - Log(Log::Normal, - "WRTIE(10) command record=%08X blocks=%d", record, ctrl.blocks); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal,"SCSI - WRTIE(10) command record=%08X blocks=%d", record, ctrl.blocks); + #endif // DISK_LOG // Do not process 0 blocks if (ctrl.blocks == 0) { @@ -929,9 +1015,9 @@ void FASTCALL SCSIDEV::CmdSeek10() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "SEEK(10) Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - SEEK(10) Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -984,10 +1070,9 @@ void FASTCALL SCSIDEV::CmdVerify() ctrl.blocks <<= 8; ctrl.blocks |= ctrl.cmd[8]; -#if defined(DISK_LOG) - Log(Log::Normal, - "VERIFY command record=%08X blocks=%d", record, ctrl.blocks); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal,"SCSI - VERIFY command record=%08X blocks=%d", record, ctrl.blocks); + #endif // DISK_LOG // Do not process 0 blocks if (ctrl.blocks == 0) { @@ -1057,12 +1142,11 @@ void FASTCALL SCSIDEV::CmdSynchronizeCache() void FASTCALL SCSIDEV::CmdReadDefectData10() { DWORD lun; - ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "READ DEFECT DATA(10) Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - READ DEFECT DATA(10) Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1092,7 +1176,6 @@ void FASTCALL SCSIDEV::CmdReadDefectData10() void FASTCALL SCSIDEV::CmdReadToc() { DWORD lun; - ASSERT(this); // Logical Unit @@ -1218,9 +1301,9 @@ void FASTCALL SCSIDEV::CmdModeSelect10() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SELECT10 Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - MODE SELECT10 Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1252,9 +1335,9 @@ void FASTCALL SCSIDEV::CmdModeSense10() ASSERT(this); -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SENSE(10) Command "); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - MODE SENSE(10) Command "); + #endif // DISK_LOG // Logical Unit lun = (ctrl.cmd[1] >> 5) & 0x07; @@ -1267,8 +1350,7 @@ void FASTCALL SCSIDEV::CmdModeSense10() ctrl.length = ctrl.unit[lun]->ModeSense10(ctrl.cmd, ctrl.buffer); ASSERT(ctrl.length >= 0); if (ctrl.length == 0) { - Log(Log::Warning, - "Not supported MODE SENSE(10) page $%02X", ctrl.cmd[2]); + Log(Log::Warning,"SCSI - Not supported MODE SENSE(10) page $%02X", ctrl.cmd[2]); // Failure (Error) Error(); @@ -1394,16 +1476,16 @@ void FASTCALL SCSIDEV::CmdSendMessage10() //--------------------------------------------------------------------------- void FASTCALL SCSIDEV::Send() { -#ifdef RASCSI + #ifdef RASCSI int len; -#endif // RASCSI + #endif // RASCSI BOOL result; ASSERT(this); ASSERT(!ctrl.bus->GetREQ()); ASSERT(ctrl.bus->GetIO()); -#ifdef RASCSI + #ifdef RASCSI //if Length! = 0, send if (ctrl.length != 0) { len = ctrl.bus->SendHandShake( @@ -1420,20 +1502,20 @@ void FASTCALL SCSIDEV::Send() ctrl.length = 0; return; } -#else + #else // offset and length ASSERT(ctrl.length >= 1); ctrl.offset++; ctrl.length--; // Immediately after ACK is asserted, if the data has been - // set by SendNext, raise the request - if (ctrl.length != 0) { + // set by SendNext, raise the request + if (ctrl.length != 0) { // Signal line operated by the target ctrl.bus->SetREQ(TRUE); return; } -#endif // RASCSI + #endif // RASCSI // Block subtraction, result initialization ctrl.blocks--; @@ -1442,11 +1524,11 @@ void FASTCALL SCSIDEV::Send() // Processing after data collection (read/data-in only) if (ctrl.phase == BUS::datain) { if (ctrl.blocks != 0) { - // // set next buffer (set offset, length) + // set next buffer (set offset, length) result = XferIn(ctrl.buffer); -#ifndef RASCSI + #ifndef RASCSI ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); -#endif // RASCSI + #endif // RASCSI } } @@ -1460,10 +1542,10 @@ void FASTCALL SCSIDEV::Send() if (ctrl.blocks != 0){ ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); -#ifndef RASCSI + #ifndef RASCSI // Signal line operated by the target ctrl.bus->SetREQ(TRUE); -#endif // RASCSI + #endif // RASCSI return; } @@ -1556,9 +1638,9 @@ void FASTCALL SCSIDEV::Receive() // Command phase case BUS::command: ctrl.cmd[ctrl.offset] = data; -#if defined(DISK_LOG) - Log(Log::Normal, "Command phase $%02X", data); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - Command phase $%02X", data); + #endif // DISK_LOG // Set the length again with the first data (offset 0) if (ctrl.offset == 0) { @@ -1572,9 +1654,9 @@ void FASTCALL SCSIDEV::Receive() // Message out phase case BUS::msgout: ctrl.message = data; -#if defined(DISK_LOG) - Log(Log::Normal, "Message out phase $%02X", data); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - Message out phase $%02X", data); + #endif // DISK_LOG break; // Data out phase @@ -1598,6 +1680,7 @@ void FASTCALL SCSIDEV::Receive() //--------------------------------------------------------------------------- void FASTCALL SCSIDEV::Receive() #else + //--------------------------------------------------------------------------- // // Continue receiving data @@ -1606,9 +1689,9 @@ void FASTCALL SCSIDEV::Receive() void FASTCALL SCSIDEV::ReceiveNext() #endif // RASCSI { -#ifdef RASCSI + #ifdef RASCSI int len; -#endif // RASCSI + #endif // RASCSI BOOL result; int i; BYTE data; @@ -1619,7 +1702,7 @@ void FASTCALL SCSIDEV::ReceiveNext() ASSERT(!ctrl.bus->GetREQ()); ASSERT(!ctrl.bus->GetIO()); -#ifdef RASCSI + #ifdef RASCSI // Length != 0 if received if (ctrl.length != 0) { // Receive @@ -1637,7 +1720,7 @@ void FASTCALL SCSIDEV::ReceiveNext() ctrl.length = 0;; return; } -#else + #else // Offset and Length ASSERT(ctrl.length >= 1); ctrl.offset++; @@ -1649,7 +1732,7 @@ void FASTCALL SCSIDEV::ReceiveNext() ctrl.bus->SetREQ(TRUE); return; } -#endif // RASCSI + #endif // RASCSI // Block subtraction, result initialization ctrl.blocks--; @@ -1696,10 +1779,10 @@ void FASTCALL SCSIDEV::ReceiveNext() if (ctrl.blocks != 0){ ASSERT(ctrl.length > 0); ASSERT(ctrl.offset == 0); -#ifndef RASCSI + #ifndef RASCSI // Signal line operated by the target ctrl.bus->SetREQ(TRUE); -#endif // RASCSI + #endif // RASCSI return; } @@ -1707,7 +1790,7 @@ void FASTCALL SCSIDEV::ReceiveNext() switch (ctrl.phase) { // Command phase case BUS::command: -#ifdef RASCSI + #ifdef RASCSI // Command data transfer len = 6; if (ctrl.buffer[0] >= 0x20 && ctrl.buffer[0] <= 0x7D) { @@ -1716,11 +1799,11 @@ void FASTCALL SCSIDEV::ReceiveNext() } for (i = 0; i < len; i++) { ctrl.cmd[i] = (DWORD)ctrl.buffer[i]; -#if defined(DISK_LOG) - Log(Log::Normal, "Command $%02X", ctrl.cmd[i]); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal, "SCSI - Command $%02X", ctrl.cmd[i]); + #endif // DISK_LOG } -#endif // RASCSI + #endif // RASCSI // Execution Phase Execute(); @@ -1734,10 +1817,10 @@ void FASTCALL SCSIDEV::ReceiveNext() ctrl.offset = 0; ctrl.length = 1; ctrl.blocks = 1; -#ifndef RASCSI + #ifndef RASCSI // Request message ctrl.bus->SetREQ(TRUE); -#endif // RASCSI + #endif // RASCSI return; } @@ -1750,20 +1833,18 @@ void FASTCALL SCSIDEV::ReceiveNext() // ABORT if (data == 0x06) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code ABORT $%02X", data); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal,"SCSI - Message code ABORT $%02X", data); + #endif // DISK_LOG BusFree(); return; } // BUS DEVICE RESET if (data == 0x0C) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code BUS DEVICE RESET $%02X", data); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal,"SCSI - Message code BUS DEVICE RESET $%02X", data); + #endif // DISK_LOG scsi.syncoffset = 0; BusFree(); return; @@ -1771,18 +1852,16 @@ void FASTCALL SCSIDEV::ReceiveNext() // IDENTIFY if (data >= 0x80) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code IDENTIFY $%02X", data); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal,"SCSI - Message code IDENTIFY $%02X", data); + #endif // DISK_LOG } // Extended Message if (data == 0x01) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code EXTENDED MESSAGE $%02X", data); -#endif // DISK_LOG + #if defined(DISK_LOG) + Log(Log::Normal,"SCSI - Message code EXTENDED MESSAGE $%02X", data); + #endif // DISK_LOG // Check only when synchronous transfer is possible if (!scsi.syncenable || scsi.msb[i + 2] != 0x01) { diff --git a/src/raspberrypi/controllers/scsidev_ctrl.h b/src/raspberrypi/controllers/scsidev_ctrl.h index f830b2d0..8beec1df 100644 --- a/src/raspberrypi/controllers/scsidev_ctrl.h +++ b/src/raspberrypi/controllers/scsidev_ctrl.h @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI device controller ] +// [ SCSI device controller ] // //--------------------------------------------------------------------------- #pragma once @@ -43,100 +43,66 @@ public: #ifdef RASCSI SCSIDEV(); #else - SCSIDEV(Device *dev); + SCSIDEV(Device *dev); // Constructor #endif // RASCSI - // Constructor - void FASTCALL Reset(); - // Device Reset + void FASTCALL Reset(); // Device Reset // 外部API - BUS::phase_t FASTCALL Process(); - // Run + BUS::phase_t FASTCALL Process(); // Run - void FASTCALL SyncTransfer(BOOL enable) { scsi.syncenable = enable; } - // Synchronouse transfer enable setting + void FASTCALL SyncTransfer(BOOL enable) { scsi.syncenable = enable; } // Synchronouse transfer enable setting // Other - BOOL FASTCALL IsSASI() const {return FALSE;} - // SASI Check - BOOL FASTCALL IsSCSI() const {return TRUE;} - // SCSI check + BOOL FASTCALL IsSASI() const {return FALSE;} // SASI Check + BOOL FASTCALL IsSCSI() const {return TRUE;} // SCSI check private: // Phase - void FASTCALL BusFree(); - // Bus free phase - void FASTCALL Selection(); - // Selection phase - void FASTCALL Execute(); - // Execution phase - void FASTCALL MsgOut(); - // Message out phase - void FASTCALL Error(); - // Common erorr handling + void FASTCALL BusFree(); // Bus free phase + void FASTCALL Selection(); // Selection phase + void FASTCALL Execute(); // Execution phase + void FASTCALL MsgOut(); // Message out phase + void FASTCALL Error(); // Common erorr handling // commands - void FASTCALL CmdInquiry(); - // INQUIRY command - void FASTCALL CmdModeSelect(); - // MODE SELECT command - void FASTCALL CmdModeSense(); - // MODE SENSE command - void FASTCALL CmdStartStop(); - // START STOP UNIT command - void FASTCALL CmdSendDiag(); - // SEND DIAGNOSTIC command - void FASTCALL CmdRemoval(); - // PREVENT/ALLOW MEDIUM REMOVAL command - void FASTCALL CmdReadCapacity(); - // READ CAPACITY command - void FASTCALL CmdRead10(); - // READ(10) command - void FASTCALL CmdWrite10(); - // WRITE(10) command - void FASTCALL CmdSeek10(); - // SEEK(10) command - void FASTCALL CmdVerify(); - // VERIFY command - void FASTCALL CmdSynchronizeCache(); - // SYNCHRONIZE CACHE command - void FASTCALL CmdReadDefectData10(); - // READ DEFECT DATA(10) command - void FASTCALL CmdReadToc(); - // READ TOC command - void FASTCALL CmdPlayAudio10(); - // PLAY AUDIO(10) command - void FASTCALL CmdPlayAudioMSF(); - // PLAY AUDIO MSF command - void FASTCALL CmdPlayAudioTrack(); - // PLAY AUDIO TRACK INDEX command - void FASTCALL CmdModeSelect10(); - // MODE SELECT(10) command - void FASTCALL CmdModeSense10(); - // MODE SENSE(10) command - void FASTCALL CmdGetMessage10(); - // GET MESSAGE(10) command - void FASTCALL CmdSendMessage10(); - // SEND MESSAGE(10) command + void FASTCALL CmdInquiry(); // INQUIRY command + void FASTCALL CmdModeSelect(); // MODE SELECT command + void FASTCALL CmdReserve6(); // RESERVE(6) command + void FASTCALL CmdReserve10(); // RESERVE(10) command + void FASTCALL CmdRelease6(); // RELEASE(6) command + void FASTCALL CmdRelease10(); // RELEASE(10) command + void FASTCALL CmdModeSense(); // MODE SENSE command + void FASTCALL CmdStartStop(); // START STOP UNIT command + void FASTCALL CmdSendDiag(); // SEND DIAGNOSTIC command + void FASTCALL CmdRemoval(); // PREVENT/ALLOW MEDIUM REMOVAL command + void FASTCALL CmdReadCapacity(); // READ CAPACITY command + void FASTCALL CmdRead10(); // READ(10) command + void FASTCALL CmdWrite10(); // WRITE(10) command + void FASTCALL CmdSeek10(); // SEEK(10) command + void FASTCALL CmdVerify(); // VERIFY command + void FASTCALL CmdSynchronizeCache(); // SYNCHRONIZE CACHE command + void FASTCALL CmdReadDefectData10(); // READ DEFECT DATA(10) command + void FASTCALL CmdReadToc(); // READ TOC command + void FASTCALL CmdPlayAudio10(); // PLAY AUDIO(10) command + void FASTCALL CmdPlayAudioMSF(); // PLAY AUDIO MSF command + void FASTCALL CmdPlayAudioTrack(); // PLAY AUDIO TRACK INDEX command + void FASTCALL CmdModeSelect10(); // MODE SELECT(10) command + void FASTCALL CmdModeSense10(); // MODE SENSE(10) command + void FASTCALL CmdGetMessage10(); // GET MESSAGE(10) command + void FASTCALL CmdSendMessage10(); // SEND MESSAGE(10) command // データ転送 - void FASTCALL Send(); - // Send data -#ifndef RASCSI - void FASTCALL SendNext(); - // Continue sending data -#endif // RASCSI - void FASTCALL Receive(); - // Receive data -#ifndef RASCSI - void FASTCALL ReceiveNext(); - // Continue receiving data -#endif // RASCSI - BOOL FASTCALL XferMsg(DWORD msg); - // Data transfer message + void FASTCALL Send(); // Send data + #ifndef RASCSI + void FASTCALL SendNext(); // Continue sending data + #endif // RASCSI + void FASTCALL Receive(); // Receive data + #ifndef RASCSI + void FASTCALL ReceiveNext(); // Continue receiving data + #endif // RASCSI + BOOL FASTCALL XferMsg(DWORD msg); // Data transfer message - scsi_t scsi; - // Internal data + scsi_t scsi; // Internal data }; From 6d79023a5c957e52e3fca1c2b6fcef1f3e5064b8 Mon Sep 17 00:00:00 2001 From: PhrAx <68938882+phrax0@users.noreply.github.com> Date: Sun, 7 Mar 2021 17:29:30 -0800 Subject: [PATCH 21/22] FIxing code and comment alignment going through the various files and putting comments on one line for easier reading. --- src/raspberrypi/devices/cfilesystem.h | 889 ++++++++----------- src/raspberrypi/devices/ctapdriver.h | 27 +- src/raspberrypi/devices/disk.cpp | 24 +- src/raspberrypi/devices/disk.h | 350 +++----- src/raspberrypi/devices/sasihd.cpp | 18 +- src/raspberrypi/devices/sasihd.h | 19 +- src/raspberrypi/devices/scsi_host_bridge.cpp | 70 +- src/raspberrypi/devices/scsi_host_bridge.h | 172 ++-- src/raspberrypi/devices/scsicd.cpp | 8 +- src/raspberrypi/devices/scsicd.h | 224 ++--- src/raspberrypi/devices/scsihd.cpp | 8 +- src/raspberrypi/devices/scsihd.h | 22 +- src/raspberrypi/devices/scsihd_apple.cpp | 8 +- src/raspberrypi/devices/scsihd_apple.h | 18 +- src/raspberrypi/devices/scsihd_nec.cpp | 8 +- src/raspberrypi/devices/scsihd_nec.h | 46 +- src/raspberrypi/devices/scsimo.cpp | 8 +- src/raspberrypi/devices/scsimo.h | 30 +- 18 files changed, 751 insertions(+), 1198 deletions(-) diff --git a/src/raspberrypi/devices/cfilesystem.h b/src/raspberrypi/devices/cfilesystem.h index 42cfa146..bf9665d2 100644 --- a/src/raspberrypi/devices/cfilesystem.h +++ b/src/raspberrypi/devices/cfilesystem.h @@ -31,7 +31,7 @@ #define FS_CANTACCESS 0xFFFFFFFB ///< ディレクトリやボリュームラベルはアクセス不可 #define FS_NOTOPENED 0xFFFFFFFA ///< 指定したハンドルはオープンされていない #define FS_INVALIDMEM 0xFFFFFFF9 ///< メモリ管理領域が破壊された -#define FS_OUTOFMEM 0xFFFFFFF8 ///< 実行に必要なメモリがない +#define FS_OUTOFMEM 0xFFFFFFF8 ///< 実行に必要なメモリがない #define FS_INVALIDPTR 0xFFFFFFF7 ///< 無効なメモリ管理ポインタを指定した #define FS_INVALIDENV 0xFFFFFFF6 ///< 不正な環境を指定した #define FS_ILLEGALFMT 0xFFFFFFF5 ///< 実行ファイルのフォーマットが異常 @@ -41,22 +41,22 @@ #define FS_INVALIDDRV 0xFFFFFFF1 ///< ドライブ指定に誤りがある #define FS_DELCURDIR 0xFFFFFFF0 ///< カレントディレクトリは削除できない #define FS_NOTIOCTRL 0xFFFFFFEF ///< IOCTRLできないデバイス -#define FS_LASTFILE 0xFFFFFFEE ///< これ以上ファイルが見つからない +#define FS_LASTFILE 0xFFFFFFEE ///< これ以上ファイルが見つからない #define FS_CANTWRITE 0xFFFFFFED ///< 指定のファイルは書き込みできない #define FS_DIRALREADY 0xFFFFFFEC ///< 指定のディレクトリは既に登録されている #define FS_CANTDELETE 0xFFFFFFEB ///< ファイルがあるので削除できない #define FS_CANTRENAME 0xFFFFFFEA ///< ファイルがあるのでリネームできない -#define FS_DISKFULL 0xFFFFFFE9 ///< ディスクが一杯でファイルが作れない -#define FS_DIRFULL 0xFFFFFFE8 ///< ディレクトリが一杯でファイルが作れない -#define FS_CANTSEEK 0xFFFFFFE7 ///< 指定の位置にはシークできない +#define FS_DISKFULL 0xFFFFFFE9 ///< ディスクが一杯でファイルが作れない +#define FS_DIRFULL 0xFFFFFFE8 ///< ディレクトリが一杯でファイルが作れない +#define FS_CANTSEEK 0xFFFFFFE7 ///< 指定の位置にはシークできない #define FS_SUPERVISOR 0xFFFFFFE6 ///< スーパーバイザ状態でスーパバイザ指定した #define FS_THREADNAME 0xFFFFFFE5 ///< 同じスレッド名が存在する -#define FS_BUFWRITE 0xFFFFFFE4 ///< プロセス間通信のバッファが書込み禁止 +#define FS_BUFWRITE 0xFFFFFFE4 ///< プロセス間通信のバッファが書込み禁止 #define FS_BACKGROUND 0xFFFFFFE3 ///< バックグラウンドプロセスを起動できない #define FS_OUTOFLOCK 0xFFFFFFE0 ///< ロック領域が足りない -#define FS_LOCKED 0xFFFFFFDF ///< ロックされていてアクセスできない +#define FS_LOCKED 0xFFFFFFDF ///< ロックされていてアクセスできない #define FS_DRIVEOPENED 0xFFFFFFDE ///< 指定のドライブはハンドラがオープンされている -#define FS_LINKOVER 0xFFFFFFDD ///< シンボリックリンクネストが16回を超えた +#define FS_LINKOVER 0xFFFFFFDD ///< シンボリックリンクネストが16回を超えた #define FS_FILEEXIST 0xFFFFFFB0 ///< ファイルが存在する #define FS_FATAL_MEDIAOFFLINE 0xFFFFFFA3 ///< メディアが入っていない @@ -64,7 +64,7 @@ #define FS_FATAL_INVALIDCOMMAND 0xFFFFFFA1 ///< 不正なコマンド番号 #define FS_FATAL_INVALIDUNIT 0xFFFFFFA0 ///< 不正なユニット番号 -#define HUMAN68K_PATH_MAX 96 ///< Human68kのパス最大長 +#define HUMAN68K_PATH_MAX 96 ///< Human68kのパス最大長 //=========================================================================== // @@ -80,62 +80,62 @@ namespace Human68k { AT_VOLUME = 0x08, ///< ボリュームラベル属性 AT_DIRECTORY = 0x10, ///< ディレクトリ属性 AT_ARCHIVE = 0x20, ///< アーカイブ属性 - AT_ALL = 0xFF, ///< 全ての属性ビットが1 + AT_ALL = 0xFF, ///< 全ての属性ビットが1 }; /// ファイルオープンモード enum open_t { - OP_READ = 0, ///< 読み込み - OP_WRITE = 1, ///< 書き込み - OP_FULL = 2, ///< 読み書き - OP_MASK = 0x0F, ///< 判定用マスク + OP_READ = 0, ///< 読み込み + OP_WRITE = 1, ///< 書き込み + OP_FULL = 2, ///< 読み書き + OP_MASK = 0x0F, ///< 判定用マスク OP_SHARE_NONE = 0x10, ///< 共有禁止 OP_SHARE_READ = 0x20, ///< 読み込み共有 OP_SHARE_WRITE = 0x30, ///< 書き込み共有 OP_SHARE_FULL = 0x40, ///< 読み書き共有 OP_SHARE_MASK = 0x70, ///< 共有判定用マスク - OP_SPECIAL = 0x100, ///< 辞書アクセス + OP_SPECIAL = 0x100, ///< 辞書アクセス }; /// シーク種類 enum seek_t { - SK_BEGIN = 0, ///< ファイル先頭から - SK_CURRENT = 1, ///< 現在位置から - SK_END = 2, ///< ファイル末尾から + SK_BEGIN = 0, ///< ファイル先頭から + SK_CURRENT = 1, ///< 現在位置から + SK_END = 2, ///< ファイル末尾から }; /// メディアバイト enum media_t { - MEDIA_2DD_10 = 0xE0, ///< 2DD/10セクタ - MEDIA_1D_9 = 0xE5, ///< 1D/9セクタ - MEDIA_2D_9 = 0xE6, ///< 2D/9セクタ - MEDIA_1D_8 = 0xE7, ///< 1D/8セクタ - MEDIA_2D_8 = 0xE8, ///< 2D/8セクタ - MEDIA_2HT = 0xEA, ///< 2HT - MEDIA_2HS = 0xEB, ///< 2HS - MEDIA_2HDE = 0xEC, ///< 2DDE - MEDIA_1DD_9 = 0xEE, ///< 1DD/9セクタ - MEDIA_1DD_8 = 0xEF, ///< 1DD/8セクタ - MEDIA_MANUAL = 0xF1, ///< リモートドライブ (手動イジェクト) - MEDIA_REMOVABLE = 0xF2, ///< リモートドライブ (リムーバブル) - MEDIA_REMOTE = 0xF3, ///< リモートドライブ - MEDIA_DAT = 0xF4, ///< SCSI-DAT - MEDIA_CDROM = 0xF5, ///< SCSI-CDROM - MEDIA_MO = 0xF6, ///< SCSI-MO - MEDIA_SCSI_HD = 0xF7, ///< SCSI-HD - MEDIA_SASI_HD = 0xF8, ///< SASI-HD - MEDIA_RAMDISK = 0xF9, ///< RAMディスク - MEDIA_2HQ = 0xFA, ///< 2HQ - MEDIA_2DD_8 = 0xFB, ///< 2DD/8セクタ - MEDIA_2DD_9 = 0xFC, ///< 2DD/9セクタ - MEDIA_2HC = 0xFD, ///< 2HC - MEDIA_2HD = 0xFE, ///< 2HD + MEDIA_2DD_10 = 0xE0, ///< 2DD/10セクタ + MEDIA_1D_9 = 0xE5, ///< 1D/9セクタ + MEDIA_2D_9 = 0xE6, ///< 2D/9セクタ + MEDIA_1D_8 = 0xE7, ///< 1D/8セクタ + MEDIA_2D_8 = 0xE8, ///< 2D/8セクタ + MEDIA_2HT = 0xEA, ///< 2HT + MEDIA_2HS = 0xEB, ///< 2HS + MEDIA_2HDE = 0xEC, ///< 2DDE + MEDIA_1DD_9 = 0xEE, ///< 1DD/9セクタ + MEDIA_1DD_8 = 0xEF, ///< 1DD/8セクタ + MEDIA_MANUAL = 0xF1, ///< リモートドライブ (手動イジェクト) + MEDIA_REMOVABLE = 0xF2, ///< リモートドライブ (リムーバブル) + MEDIA_REMOTE = 0xF3, ///< リモートドライブ + MEDIA_DAT = 0xF4, ///< SCSI-DAT + MEDIA_CDROM = 0xF5, ///< SCSI-CDROM + MEDIA_MO = 0xF6, ///< SCSI-MO + MEDIA_SCSI_HD = 0xF7, ///< SCSI-HD + MEDIA_SASI_HD = 0xF8, ///< SASI-HD + MEDIA_RAMDISK = 0xF9, ///< RAMディスク + MEDIA_2HQ = 0xFA, ///< 2HQ + MEDIA_2DD_8 = 0xFB, ///< 2DD/8セクタ + MEDIA_2DD_9 = 0xFC, ///< 2DD/9セクタ + MEDIA_2HC = 0xFD, ///< 2HC + MEDIA_2HD = 0xFE, ///< 2HD }; /// namests構造体 struct namests_t { BYTE wildcard; ///< ワイルドカード文字数 - BYTE drive; ///< ドライブ番号 + BYTE drive; ///< ドライブ番号 BYTE path[65]; ///< パス(サブディレクトリ+/) BYTE name[8]; ///< ファイル名 (PADDING 0x20) BYTE ext[3]; ///< 拡張子 (PADDING 0x20) @@ -150,37 +150,37 @@ namespace Human68k { /// files構造体 struct files_t { - BYTE fatr; ///< + 0 検索する属性 読込専用 - // BYTE drive; ///< + 1 ドライブ番号 読込専用 - DWORD sector; ///< + 2 ディレクトリのセクタ DOS _FILES先頭アドレスで代用 - // WORD cluster; ///< + 6 ディレクトリのクラスタ 詳細不明 (未使用) - WORD offset; ///< + 8 ディレクトリエントリ 書込専用 - // BYTE name[8]; ///< +10 作業用ファイル名 読込専用 (未使用) - // BYTE ext[3]; ///< +18 作業用拡張子 読込専用 (未使用) - BYTE attr; ///< +21 ファイル属性 書込専用 - WORD time; ///< +22 最終変更時刻 書込専用 - WORD date; ///< +24 最終変更月日 書込専用 - DWORD size; ///< +26 ファイルサイズ 書込専用 + BYTE fatr; ///< + 0 検索する属性 読込専用 + // BYTE drive; ///< + 1 ドライブ番号 読込専用 + DWORD sector; ///< + 2 ディレクトリのセクタ DOS _FILES先頭アドレスで代用 + // WORD cluster; ///< + 6 ディレクトリのクラスタ 詳細不明 (未使用) + WORD offset; ///< + 8 ディレクトリエントリ 書込専用 + // BYTE name[8]; ///< +10 作業用ファイル名 読込専用 (未使用) + // BYTE ext[3]; ///< +18 作業用拡張子 読込専用 (未使用) + BYTE attr; ///< +21 ファイル属性 書込専用 + WORD time; ///< +22 最終変更時刻 書込専用 + WORD date; ///< +24 最終変更月日 書込専用 + DWORD size; ///< +26 ファイルサイズ 書込専用 BYTE full[23]; ///< +30 フルファイル名 書込専用 }; /// FCB構造体 struct fcb_t { - // BYTE pad00[6]; ///< + 0~+ 5 (未使用) + // BYTE pad00[6]; ///< + 0~+ 5 (未使用) DWORD fileptr; ///< + 6~+ 9 ファイルポインタ - // BYTE pad01[4]; ///< +10~+13 (未使用) - WORD mode; ///< +14~+15 オープンモード - // BYTE pad02[16]; ///< +16~+31 (未使用) - // DWORD zero; ///< +32~+35 オープンのとき0が書き込まれている (未使用) - // BYTE name[8]; ///< +36~+43 ファイル名 (PADDING 0x20) (未使用) - // BYTE ext[3]; ///< +44~+46 拡張子 (PADDING 0x20) (未使用) - BYTE attr; ///< +47 ファイル属性 - // BYTE add[10]; ///< +48~+57 ファイル名追加 (PADDING 0x00) (未使用) - WORD time; ///< +58~+59 最終変更時刻 - WORD date; ///< +60~+61 最終変更月日 - // WORD cluster; ///< +62~+63 クラスタ番号 (未使用) - DWORD size; ///< +64~+67 ファイルサイズ - // BYTE pad03[28]; ///< +68~+95 FATキャッシュ (未使用) + // BYTE pad01[4]; ///< +10~+13 (未使用) + WORD mode; ///< +14~+15 オープンモード + // BYTE pad02[16]; ///< +16~+31 (未使用) + // DWORD zero; ///< +32~+35 オープンのとき0が書き込まれている (未使用) + // BYTE name[8]; ///< +36~+43 ファイル名 (PADDING 0x20) (未使用) + // BYTE ext[3]; ///< +44~+46 拡張子 (PADDING 0x20) (未使用) + BYTE attr; ///< +47 ファイル属性 + // BYTE add[10]; ///< +48~+57 ファイル名追加 (PADDING 0x00) (未使用) + WORD time; ///< +58~+59 最終変更時刻 + WORD date; ///< +60~+61 最終変更月日 + // WORD cluster; ///< +62~+63 クラスタ番号 (未使用) + DWORD size; ///< +64~+67 ファイルサイズ + // BYTE pad03[28]; ///< +68~+95 FATキャッシュ (未使用) }; /// capacity構造体 @@ -188,7 +188,7 @@ namespace Human68k { WORD freearea; ///< + 0 使用可能なクラスタ数 WORD clusters; ///< + 2 総クラスタ数 WORD sectors; ///< + 4 クラスタあたりのセクタ数 - WORD bytes; ///< + 6 セクタ当たりのバイト数 + WORD bytes; ///< + 6 セクタ当たりのバイト数 }; /// ctrldrive構造体 @@ -201,7 +201,7 @@ namespace Human68k { struct dpb_t { WORD sector_size; ///< + 0 1セクタ当りのバイト数 BYTE cluster_size; ///< + 2 1クラスタ当りのセクタ数-1 - BYTE shift; ///< + 3 クラスタ→セクタのシフト数 + BYTE shift; ///< + 3 クラスタ→セクタのシフト数 WORD fat_sector; ///< + 4 FATの先頭セクタ番号 BYTE fat_max; ///< + 6 FAT領域の個数 BYTE fat_size; ///< + 7 FATの占めるセクタ数(複写分を除く) @@ -209,28 +209,28 @@ namespace Human68k { WORD data_sector; ///< +10 データ領域の先頭セクタ番号 WORD cluster_max; ///< +12 総クラスタ数+1 WORD root_sector; ///< +14 ルートディレクトリの先頭セクタ番号 - // DWORD driverentry; ///< +16 デバイスドライバへのポインタ (未使用) - BYTE media; ///< +20 メディア識別子 - // BYTE flag; ///< +21 DPB使用フラグ (未使用) + // DWORD driverentry; ///< +16 デバイスドライバへのポインタ (未使用) + BYTE media; ///< +20 メディア識別子 + // BYTE flag; ///< +21 DPB使用フラグ (未使用) }; /// ディレクトリエントリ構造体 struct dirent_t { BYTE name[8]; ///< + 0 ファイル名 (PADDING 0x20) BYTE ext[3]; ///< + 8 拡張子 (PADDING 0x20) - BYTE attr; ///< +11 ファイル属性 + BYTE attr; ///< +11 ファイル属性 BYTE add[10]; ///< +12 ファイル名追加 (PADDING 0x00) - WORD time; ///< +22 最終変更時刻 - WORD date; ///< +24 最終変更月日 + WORD time; ///< +22 最終変更時刻 + WORD date; ///< +24 最終変更月日 WORD cluster; ///< +26 クラスタ番号 - DWORD size; ///< +28 ファイルサイズ + DWORD size; ///< +28 ファイルサイズ }; /// IOCTRLパラメータ共用体 union ioctrl_t { BYTE buffer[8]; ///< バイト単位でのアクセス DWORD param; ///< パラメータ(先頭4バイト) - WORD media; ///< メディアバイト(先頭2バイト) + WORD media; ///< メディアバイト(先頭2バイト) }; /// コマンドライン引数構造体 @@ -328,42 +328,23 @@ Human68k側のファイル名は、ホスト側のファイルシステムの名 内部動作フラグとメディアバイト偽装などを見越した将来の拡張用。 */ enum { - WINDRV_OPT_REMOVE = 0x00000001, - ///< Bit 0: ファイル削除処理 0:直接 1:ごみ箱 - WINDRV_OPT_ALPHABET = 0x00000020, - ///< Bit 5: ファイル名比較 Alphabet区別 0:なし 1:あり 0:-C 1:+C - WINDRV_OPT_COMPARE_LENGTH = 0x00000040, - ///< Bit 6: ファイル名比較 文字数(未実装) 0:18+3 1:8+3 0:+T 1:-T - WINDRV_OPT_CONVERT_LENGTH = 0x00000080, - ///< Bit 7: ファイル名変換 文字数 0:18+3 1:8+3 0:-A 1:+A - - WINDRV_OPT_CONVERT_SPACE = 0x00000100, - ///< Bit 8: ファイル名変換 スペース 0:なし 1:'_' - WINDRV_OPT_CONVERT_BADCHAR = 0x00000200, - ///< Bit 9: ファイル名変換 無効な文字 0:なし 1:'_' - WINDRV_OPT_CONVERT_HYPHENS = 0x00000400, - ///< Bit10: ファイル名変換 中間のハイフン 0:なし 1:'_' - WINDRV_OPT_CONVERT_HYPHEN = 0x00000800, - ///< Bit11: ファイル名変換 先頭のハイフン 0:なし 1:'_' - WINDRV_OPT_CONVERT_PERIODS = 0x00001000, - ///< Bit12: ファイル名変換 中間のピリオド 0:なし 1:'_' - WINDRV_OPT_CONVERT_PERIOD = 0x00002000, - ///< Bit13: ファイル名変換 先頭のピリオド 0:なし 1:'_' - - WINDRV_OPT_REDUCED_SPACE = 0x00010000, - ///< Bit16: ファイル名短縮 スペース 0:なし 1:短縮 - WINDRV_OPT_REDUCED_BADCHAR = 0x00020000, - ///< Bit17: ファイル名短縮 無効な文字 0:なし 1:短縮 - WINDRV_OPT_REDUCED_HYPHENS = 0x00040000, - ///< Bit18: ファイル名短縮 中間のハイフン 0:なし 1:短縮 - WINDRV_OPT_REDUCED_HYPHEN = 0x00080000, - ///< Bit19: ファイル名短縮 先頭のハイフン 0:なし 1:短縮 - WINDRV_OPT_REDUCED_PERIODS = 0x00100000, - ///< Bit20: ファイル名短縮 中間のピリオド 0:なし 1:短縮 - WINDRV_OPT_REDUCED_PERIOD = 0x00200000, - ///< Bit21: ファイル名短縮 先頭のピリオド 0:なし 1:短縮 - - // Bit24~30 ファイル重複防止マーク 0:自動 1~127:文字 + WINDRV_OPT_REMOVE = 0x00000001, ///< Bit 0: ファイル削除処理 0:直接 1:ごみ箱 + WINDRV_OPT_ALPHABET = 0x00000020, ///< Bit 5: ファイル名比較 Alphabet区別 0:なし 1:あり 0:-C 1:+C + WINDRV_OPT_COMPARE_LENGTH = 0x00000040, ///< Bit 6: ファイル名比較 文字数(未実装) 0:18+3 1:8+3 0:+T 1:-T + WINDRV_OPT_CONVERT_LENGTH = 0x00000080, ///< Bit 7: ファイル名変換 文字数 0:18+3 1:8+3 0:-A 1:+A + WINDRV_OPT_CONVERT_SPACE = 0x00000100, ///< Bit 8: ファイル名変換 スペース 0:なし 1:'_' + WINDRV_OPT_CONVERT_BADCHAR = 0x00000200, ///< Bit 9: ファイル名変換 無効な文字 0:なし 1:'_' + WINDRV_OPT_CONVERT_HYPHENS = 0x00000400, ///< Bit10: ファイル名変換 中間のハイフン 0:なし 1:'_' + WINDRV_OPT_CONVERT_HYPHEN = 0x00000800, ///< Bit11: ファイル名変換 先頭のハイフン 0:なし 1:'_' + WINDRV_OPT_CONVERT_PERIODS = 0x00001000, ///< Bit12: ファイル名変換 中間のピリオド 0:なし 1:'_' + WINDRV_OPT_CONVERT_PERIOD = 0x00002000, ///< Bit13: ファイル名変換 先頭のピリオド 0:なし 1:'_' + WINDRV_OPT_REDUCED_SPACE = 0x00010000, ///< Bit16: ファイル名短縮 スペース 0:なし 1:短縮 + WINDRV_OPT_REDUCED_BADCHAR = 0x00020000, ///< Bit17: ファイル名短縮 無効な文字 0:なし 1:短縮 + WINDRV_OPT_REDUCED_HYPHENS = 0x00040000, ///< Bit18: ファイル名短縮 中間のハイフン 0:なし 1:短縮 + WINDRV_OPT_REDUCED_HYPHEN = 0x00080000, ///< Bit19: ファイル名短縮 先頭のハイフン 0:なし 1:短縮 + WINDRV_OPT_REDUCED_PERIODS = 0x00100000, ///< Bit20: ファイル名短縮 中間のピリオド 0:なし 1:短縮 + WINDRV_OPT_REDUCED_PERIOD = 0x00200000, ///< Bit21: ファイル名短縮 先頭のピリオド 0:なし 1:短縮 + // Bit24~30 ファイル重複防止マーク 0:自動 1~127:文字 }; /// ファイルシステム動作フラグ @@ -373,12 +354,9 @@ enum { 判定が困難なデバイス(自作USBストレージとか)のための保険用。 */ enum { - FSFLAG_WRITE_PROTECT = 0x00000001, - ///< Bit0: 強制書き込み禁止 - FSFLAG_REMOVABLE = 0x00000002, - ///< Bit1: 強制リムーバブルメディア - FSFLAG_MANUAL = 0x00000004, - ///< Bit2: 強制手動イジェクト + FSFLAG_WRITE_PROTECT = 0x00000001, ///< Bit0: 強制書き込み禁止 + FSFLAG_REMOVABLE = 0x00000002, ///< Bit1: 強制リムーバブルメディア + FSFLAG_MANUAL = 0x00000004, ///< Bit2: 強制手動イジェクト }; //=========================================================================== @@ -393,17 +371,12 @@ enum { class CRing { public: // 基本ファンクション - CRing() { Init(); } - ///< デフォルトコンストラクタ - ~CRing() { Remove(); } - ///< デストラクタ final - void Init() { ASSERT(this); next = prev = this; } - ///< 初期化 + CRing() { Init(); } ///< デフォルトコンストラクタ + ~CRing() { Remove(); } ///< デストラクタ final + void Init() { ASSERT(this); next = prev = this; } ///< 初期化 - CRing* Next() const { ASSERT(this); return next; } - ///< 次の要素を取得 - CRing* Prev() const { ASSERT(this); return prev; } - ///< 前の要素を取得 + CRing* Next() const { ASSERT(this); return next; } ///< 次の要素を取得 + CRing* Prev() const { ASSERT(this); return prev; } ///< 前の要素を取得 void Insert(CRing* pRoot) { @@ -485,66 +458,48 @@ private: class CHostFilename { public: // 基本ファンクション - CHostFilename(); - ///< デフォルトコンストラクタ - static size_t Offset() { return offsetof(CHostFilename, m_szHost); } - ///< オフセット位置取得 + CHostFilename(); ///< デフォルトコンストラクタ + static size_t Offset() { return offsetof(CHostFilename, m_szHost); } ///< オフセット位置取得 - void SetHost(const TCHAR* szHost); - ///< ホスト側の名称を設定 - const TCHAR* GetHost() const { ASSERT(this); return m_szHost; } - ///< ホスト側の名称を取得 - void ConvertHuman(int nCount = -1); - ///< Human68k側の名称を変換 - void CopyHuman(const BYTE* szHuman); - ///< Human68k側の名称を複製 - BOOL isReduce() const; - ///< Human68k側の名称が加工されたか調査 - BOOL isCorrect() const { ASSERT(this); return m_bCorrect; } - ///< Human68k側のファイル名規則に合致しているか調査 - const BYTE* GetHuman() const { ASSERT(this); return m_szHuman; } - ///< Human68kファイル名を取得 - const BYTE* GetHumanLast() const { ASSERT(this); return m_pszHumanLast; } - ///< Human68kファイル名を取得 - const BYTE* GetHumanExt() const { ASSERT(this); return m_pszHumanExt; } - ///< Human68kファイル名を取得 - void SetEntryName(); - ///< Human68kディレクトリエントリを設定 + void SetHost(const TCHAR* szHost); ///< ホスト側の名称を設定 + const TCHAR* GetHost() const { ASSERT(this); return m_szHost; } ///< ホスト側の名称を取得 + void ConvertHuman(int nCount = -1); ///< Human68k側の名称を変換 + void CopyHuman(const BYTE* szHuman); ///< Human68k側の名称を複製 + BOOL isReduce() const; ///< Human68k側の名称が加工されたか調査 + BOOL isCorrect() const { ASSERT(this); return m_bCorrect; } ///< Human68k側のファイル名規則に合致しているか調査 + const BYTE* GetHuman() const { ASSERT(this); return m_szHuman; } ///< Human68kファイル名を取得 + const BYTE* GetHumanLast() const + { ASSERT(this); return m_pszHumanLast; } ///< Human68kファイル名を取得 + const BYTE* GetHumanExt() const { ASSERT(this); return m_pszHumanExt; }///< Human68kファイル名を取得 + void SetEntryName(); ///< Human68kディレクトリエントリを設定 void SetEntryAttribute(BYTE nHumanAttribute) - { ASSERT(this); m_dirHuman.attr = nHumanAttribute; } - ///< Human68kディレクトリエントリを設定 + { ASSERT(this); m_dirHuman.attr = nHumanAttribute; } ///< Human68kディレクトリエントリを設定 void SetEntrySize(DWORD nHumanSize) - { ASSERT(this); m_dirHuman.size = nHumanSize; } - ///< Human68kディレクトリエントリを設定 + { ASSERT(this); m_dirHuman.size = nHumanSize; } ///< Human68kディレクトリエントリを設定 void SetEntryDate(WORD nHumanDate) - { ASSERT(this); m_dirHuman.date = nHumanDate; } - ///< Human68kディレクトリエントリを設定 + { ASSERT(this); m_dirHuman.date = nHumanDate; } ///< Human68kディレクトリエントリを設定 void SetEntryTime(WORD nHumanTime) - { ASSERT(this); m_dirHuman.time = nHumanTime; } - ///< Human68kディレクトリエントリを設定 + { ASSERT(this); m_dirHuman.time = nHumanTime; } ///< Human68kディレクトリエントリを設定 void SetEntryCluster(WORD nHumanCluster) - { ASSERT(this); m_dirHuman.cluster = nHumanCluster; } - ///< Human68kディレクトリエントリを設定 - const Human68k::dirent_t* GetEntry() const { ASSERT(this); return &m_dirHuman; } - ///< Human68kディレクトリエントリを取得 - BOOL CheckAttribute(DWORD nHumanAttribute) const; - ///< Human68kディレクトリエントリの属性判定 + { ASSERT(this); m_dirHuman.cluster = nHumanCluster; } ///< Human68kディレクトリエントリを設定 + const Human68k::dirent_t* GetEntry() const + { ASSERT(this); return &m_dirHuman; } ///< Human68kディレクトリエントリを取得 + BOOL CheckAttribute(DWORD nHumanAttribute) const; ///< Human68kディレクトリエントリの属性判定 BOOL isSameEntry(const Human68k::dirent_t* pdirHuman) const { ASSERT(this); ASSERT(pdirHuman); return memcmp(&m_dirHuman, pdirHuman, sizeof(m_dirHuman)) == 0; } ///< Human68kディレクトリエントリの一致判定 // パス名操作 - static const BYTE* SeparateExt(const BYTE* szHuman); - ///< Human68kファイル名から拡張子を分離 + static const BYTE* SeparateExt(const BYTE* szHuman); ///< Human68kファイル名から拡張子を分離 private: static BYTE* CopyName(BYTE* pWrite, const BYTE* pFirst, const BYTE* pLast); ///< Human68k側のファイル名要素をコピー - const BYTE* m_pszHumanLast; ///< 該当エントリのHuman68k内部名の終端位置 - const BYTE* m_pszHumanExt; ///< 該当エントリのHuman68k内部名の拡張子位置 - BOOL m_bCorrect; ///< 該当エントリのHuman68k内部名が正しければ真 - BYTE m_szHuman[24]; ///< 該当エントリのHuman68k内部名 + const BYTE* m_pszHumanLast; ///< 該当エントリのHuman68k内部名の終端位置 + const BYTE* m_pszHumanExt; ///< 該当エントリのHuman68k内部名の拡張子位置 + BOOL m_bCorrect; ///< 該当エントリのHuman68k内部名が正しければ真 + BYTE m_szHuman[24]; ///< 該当エントリのHuman68k内部名 Human68k::dirent_t m_dirHuman; ///< 該当エントリのHuman68k全情報 TCHAR m_szHost[FILEPATH_MAX]; ///< 該当エントリのホスト側の名称 (可変長) }; @@ -576,80 +531,63 @@ private: class CHostPath: public CRing { /// メモリ管理用 struct ring_t { - CRing r; ///< 円環 - CHostFilename f; ///< 実体 + CRing r; ///< 円環 + CHostFilename f; ///< 実体 }; public: /// 検索用バッファ struct find_t { - DWORD count; ///< 検索実行回数 + 1 (0のときは以下の値は無効) - DWORD id; ///< 次回検索を続行するパスのエントリ識別ID - const ring_t* pos; ///< 次回検索を続行する位置 (識別ID一致時) - Human68k::dirent_t entry; ///< 次回検索を続行するエントリ内容 + DWORD count; ///< 検索実行回数 + 1 (0のときは以下の値は無効) + DWORD id; ///< 次回検索を続行するパスのエントリ識別ID + const ring_t* pos; ///< 次回検索を続行する位置 (識別ID一致時) + Human68k::dirent_t entry; ///< 次回検索を続行するエントリ内容 - void Clear() { count = 0; } - ///< 初期化 + void Clear() { count = 0; } ///< 初期化 }; // 基本ファンクション - CHostPath(); - ///< デフォルトコンストラクタ - ~CHostPath(); - ///< デストラクタ final - void Clean(); - ///< 再利用のための初期化 + CHostPath(); ///< デフォルトコンストラクタ + ~CHostPath(); ///< デストラクタ final + void Clean(); ///< 再利用のための初期化 - void SetHuman(const BYTE* szHuman); - ///< Human68k側の名称を直接指定する - void SetHost(const TCHAR* szHost); - ///< ホスト側の名称を直接指定する - BOOL isSameHuman(const BYTE* szHuman) const; - ///< Human68k側の名称を比較する - BOOL isSameChild(const BYTE* szHuman) const; - ///< Human68k側の名称を比較する - const TCHAR* GetHost() const { ASSERT(this); return m_szHost; } - ///< ホスト側の名称の獲得 + void SetHuman(const BYTE* szHuman); ///< Human68k側の名称を直接指定する + void SetHost(const TCHAR* szHost); ///< ホスト側の名称を直接指定する + BOOL isSameHuman(const BYTE* szHuman) const; ///< Human68k側の名称を比較する + BOOL isSameChild(const BYTE* szHuman) const; ///< Human68k側の名称を比較する + const TCHAR* GetHost() const { ASSERT(this); return m_szHost; } ///< ホスト側の名称の獲得 const CHostFilename* FindFilename(const BYTE* szHuman, DWORD nHumanAttribute = Human68k::AT_ALL) const; ///< ファイル名を検索 const CHostFilename* FindFilenameWildcard(const BYTE* szHuman, DWORD nHumanAttribute, find_t* pFind) const; ///< ファイル名を検索 (ワイルドカード対応) - BOOL isRefresh(); - ///< ファイル変更が行なわれたか確認 - void Refresh(); - ///< ファイル再構成 - void Backup(); - /// ホスト側のタイムスタンプを保存 - void Restore() const; - /// ホスト側のタイムスタンプを復元 - void Release(); - ///< 更新 + BOOL isRefresh(); ///< ファイル変更が行なわれたか確認 + void Refresh(); ///< ファイル再構成 + void Backup(); /// ホスト側のタイムスタンプを保存 + void Restore() const; /// ホスト側のタイムスタンプを復元 + void Release(); ///< 更新 // CHostEntryが利用する外部API - static void InitId() { g_nId = 0; } - ///< 識別ID生成用カウンタ初期化 + static void InitId() { g_nId = 0; } ///< 識別ID生成用カウンタ初期化 private: - static ring_t* Alloc(size_t nLength); - ///< ファイル名領域確保 - static void Free(ring_t* pRing); - ///< ファイル名領域解放 + static ring_t* Alloc(size_t nLength); ///< ファイル名領域確保 + static void Free(ring_t* pRing); ///< ファイル名領域解放 static int Compare(const BYTE* pFirst, const BYTE* pLast, const BYTE* pBufFirst, const BYTE* pBufLast); ///< 文字列比較 (ワイルドカード対応) - CRing m_cRing; ///< CHostFilename連結用 -#ifndef BAREMETAL - time_t m_tBackup; ///< 時刻復元用 -#else - WORD m_tBackupD; ///< 時刻復元用 - WORD m_tBackupT; ///< 時刻復元用 -#endif // BAREMETAL - BOOL m_bRefresh; ///< 更新フラグ - DWORD m_nId; ///< 識別ID (値が変化した場合は更新を意味する) - BYTE m_szHuman[HUMAN68K_PATH_MAX]; ///< 該当エントリのHuman68k内部名 - TCHAR m_szHost[FILEPATH_MAX]; ///< 該当エントリのホスト側の名称 + CRing m_cRing; ///< CHostFilename連結用 + #ifndef BAREMETAL + time_t m_tBackup; ///< 時刻復元用 + #else + WORD m_tBackupD; ///< 時刻復元用 + WORD m_tBackupT; ///< 時刻復元用 + #endif // BAREMETAL + BOOL m_bRefresh; ///< 更新フラグ + DWORD m_nId; ///< 識別ID (値が変化した場合は更新を意味する) + BYTE m_szHuman[HUMAN68K_PATH_MAX]; ///< 該当エントリのHuman68k内部名 + TCHAR m_szHost[FILEPATH_MAX]; ///< 該当エントリのホスト側の名称 - static DWORD g_nId; ///< 識別ID生成用カウンタ + static DWORD g_nId; ///< 識別ID生成用カウンタ }; //=========================================================================== @@ -676,70 +614,48 @@ private: class CHostFiles { public: // 基本ファンクション - CHostFiles() { SetKey(0); Init(); } - ///< デフォルトコンストラクタ - void Init(); - ///< 初期化 + CHostFiles() { SetKey(0); Init(); } ///< デフォルトコンストラクタ + void Init(); ///< 初期化 - void SetKey(DWORD nKey) { ASSERT(this); m_nKey = nKey; } - ///< 検索キー設定 - BOOL isSameKey(DWORD nKey) const { ASSERT(this); return m_nKey == nKey; } - ///< 検索キー比較 - void SetPath(const Human68k::namests_t* pNamests); - ///< パス名・ファイル名を内部で生成 - BOOL isRootPath() const { return m_szHumanPath[1] == '\0'; } - ///< ルートディレクトリ判定 - void SetPathWildcard() { m_nHumanWildcard = 1; } - ///< ワイルドカードによるファイル検索を有効化 - void SetPathOnly() { m_nHumanWildcard = 0xFF; } - ///< パス名のみを有効化 - BOOL isPathOnly() const { return m_nHumanWildcard == 0xFF; } - ///< パス名のみ設定か判定 + void SetKey(DWORD nKey) { ASSERT(this); m_nKey = nKey; } ///< 検索キー設定 + BOOL isSameKey(DWORD nKey) const { ASSERT(this); return m_nKey == nKey; } ///< 検索キー比較 + void SetPath(const Human68k::namests_t* pNamests); ///< パス名・ファイル名を内部で生成 + BOOL isRootPath() const { return m_szHumanPath[1] == '\0'; } ///< ルートディレクトリ判定 + void SetPathWildcard() { m_nHumanWildcard = 1; } ///< ワイルドカードによるファイル検索を有効化 + void SetPathOnly() { m_nHumanWildcard = 0xFF; } ///< パス名のみを有効化 + BOOL isPathOnly() const { return m_nHumanWildcard == 0xFF; } ///< パス名のみ設定か判定 void SetAttribute(DWORD nHumanAttribute) { m_nHumanAttribute = nHumanAttribute; } - ///< 検索属性を設定 - BOOL Find(DWORD nUnit, class CHostEntry* pEntry); - ///< Human68k側でファイルを検索しホスト側の情報を生成 - const CHostFilename* Find(CHostPath* pPath); - ///< ファイル名検索 - void SetEntry(const CHostFilename* pFilename); - ///< Human68k側の検索結果保存 - void SetResult(const TCHAR* szPath); - ///< ホスト側の名称を設定 - void AddResult(const TCHAR* szPath); - ///< ホスト側の名称にファイル名を追加 - void AddFilename(); - ///< ホスト側の名称にHuman68kの新規ファイル名を追加 + ///< 検索属性を設定 + BOOL Find(DWORD nUnit, class CHostEntry* pEntry); ///< Human68k側でファイルを検索しホスト側の情報を生成 + const CHostFilename* Find(CHostPath* pPath); ///< ファイル名検索 + void SetEntry(const CHostFilename* pFilename); ///< Human68k側の検索結果保存 + void SetResult(const TCHAR* szPath); ///< ホスト側の名称を設定 + void AddResult(const TCHAR* szPath); ///< ホスト側の名称にファイル名を追加 + void AddFilename(); ///< ホスト側の名称にHuman68kの新規ファイル名を追加 - const TCHAR* GetPath() const { ASSERT(this); return m_szHostResult; } - ///< ホスト側の名称を取得 - const Human68k::dirent_t* GetEntry() const { ASSERT(this); return &m_dirHuman; } - ///< Human68kディレクトリエントリを取得 - DWORD GetAttribute() const { ASSERT(this); return m_dirHuman.attr; } - ///< Human68k属性を取得 - WORD GetDate() const { ASSERT(this); return m_dirHuman.date; } - ///< Human68k日付を取得 - WORD GetTime() const { ASSERT(this); return m_dirHuman.time; } - ///< Human68k時刻を取得 - DWORD GetSize() const { ASSERT(this); return m_dirHuman.size; } - ///< Human68kファイルサイズを取得 - const BYTE* GetHumanFilename() const { ASSERT(this); return m_szHumanFilename; } - ///< Human68kファイル名を取得 - const BYTE* GetHumanResult() const { ASSERT(this); return m_szHumanResult; } - ///< Human68kファイル名検索結果を取得 - const BYTE* GetHumanPath() const { ASSERT(this); return m_szHumanPath; } - ///< Human68kパス名を取得 + const TCHAR* GetPath() const { ASSERT(this); return m_szHostResult; } ///< ホスト側の名称を取得 + + const Human68k::dirent_t* GetEntry() const { ASSERT(this); return &m_dirHuman; }///< Human68kディレクトリエントリを取得 + + DWORD GetAttribute() const { ASSERT(this); return m_dirHuman.attr; } ///< Human68k属性を取得 + WORD GetDate() const { ASSERT(this); return m_dirHuman.date; } ///< Human68k日付を取得 + WORD GetTime() const { ASSERT(this); return m_dirHuman.time; } ///< Human68k時刻を取得 + DWORD GetSize() const { ASSERT(this); return m_dirHuman.size; } ///< Human68kファイルサイズを取得 + const BYTE* GetHumanFilename() const { ASSERT(this); return m_szHumanFilename; }///< Human68kファイル名を取得 + const BYTE* GetHumanResult() const { ASSERT(this); return m_szHumanResult; } ///< Human68kファイル名検索結果を取得 + const BYTE* GetHumanPath() const { ASSERT(this); return m_szHumanPath; } ///< Human68kパス名を取得 private: DWORD m_nKey; ///< Human68kのFILESバッファアドレス 0なら未使用 - DWORD m_nHumanWildcard; ///< Human68kのワイルドカード情報 - DWORD m_nHumanAttribute; ///< Human68kの検索属性 - CHostPath::find_t m_findNext; ///< 次回検索位置情報 - Human68k::dirent_t m_dirHuman; ///< 検索結果 Human68kファイル情報 - BYTE m_szHumanFilename[24]; ///< Human68kのファイル名 - BYTE m_szHumanResult[24]; ///< 検索結果 Human68kファイル名 + DWORD m_nHumanWildcard; ///< Human68kのワイルドカード情報 + DWORD m_nHumanAttribute; ///< Human68kの検索属性 + CHostPath::find_t m_findNext; ///< 次回検索位置情報 + Human68k::dirent_t m_dirHuman; ///< 検索結果 Human68kファイル情報 + BYTE m_szHumanFilename[24]; ///< Human68kのファイル名 + BYTE m_szHumanResult[24]; ///< 検索結果 Human68kファイル名 BYTE m_szHumanPath[HUMAN68K_PATH_MAX]; - ///< Human68kのパス名 - TCHAR m_szHostResult[FILEPATH_MAX]; ///< 検索結果 ホスト側のフルパス名 + ///< Human68kのパス名 + TCHAR m_szHostResult[FILEPATH_MAX]; ///< 検索結果 ホスト側のフルパス名 }; //=========================================================================== @@ -751,24 +667,18 @@ class CHostFilesManager { public: #ifdef _DEBUG // 基本ファンクション - ~CHostFilesManager(); - ///< デストラクタ final + ~CHostFilesManager(); ///< デストラクタ final #endif // _DEBUG - void Init(); - ///< 初期化 (ドライバ組込み時) - void Clean(); - ///< 解放 (起動・リセット時) + void Init(); ///< 初期化 (ドライバ組込み時) + void Clean(); ///< 解放 (起動・リセット時) - CHostFiles* Alloc(DWORD nKey); - ///< 確保 - CHostFiles* Search(DWORD nKey); - ///< 検索 - void Free(CHostFiles* pFiles); - ///< 解放 + CHostFiles* Alloc(DWORD nKey); ///< 確保 + CHostFiles* Search(DWORD nKey); ///< 検索 + void Free(CHostFiles* pFiles); ///< 解放 private: /// メモリ管理用 struct ring_t { - CRing r; ///< 円環 + CRing r; ///< 円環 CHostFiles f; ///< 実体 }; @@ -783,63 +693,43 @@ private: class CHostFcb { public: // 基本ファンクション - CHostFcb() { SetKey(0); Init(); } - ///< デフォルトコンストラクタ - ~CHostFcb() { Close(); } - ///< デストラクタ final - void Init(); - ///< 初期化 + CHostFcb() { SetKey(0); Init(); } ///< デフォルトコンストラクタ + ~CHostFcb() { Close(); } ///< デストラクタ final + void Init(); ///< 初期化 - void SetKey(DWORD nKey) { ASSERT(this); m_nKey = nKey; } - ///< 検索キー設定 - BOOL isSameKey(DWORD nKey) const { ASSERT(this); return m_nKey == nKey; } - ///< 検索キー比較 - void SetUpdate() { ASSERT(this); m_bUpdate = TRUE; } - ///< 更新 - BOOL isUpdate() const { ASSERT(this); return m_bUpdate; } - ///< 更新状態取得 - BOOL SetMode(DWORD nHumanMode); - ///< ファイルオープンモードを設定 - void SetFilename(const TCHAR* szFilename); - ///< ファイル名を設定 - void SetHumanPath(const BYTE* szHumanPath); - ///< Human68kパス名を設定 - const BYTE* GetHumanPath() const { ASSERT(this); return m_szHumanPath; } - ///< Human68kパス名を取得 + void SetKey(DWORD nKey) { ASSERT(this); m_nKey = nKey; } ///< 検索キー設定 + BOOL isSameKey(DWORD nKey) const { ASSERT(this); return m_nKey == nKey; } ///< 検索キー比較 + void SetUpdate() { ASSERT(this); m_bUpdate = TRUE; } ///< 更新 + BOOL isUpdate() const { ASSERT(this); return m_bUpdate; } ///< 更新状態取得 + BOOL SetMode(DWORD nHumanMode); ///< ファイルオープンモードを設定 + void SetFilename(const TCHAR* szFilename); ///< ファイル名を設定 + void SetHumanPath(const BYTE* szHumanPath); ///< Human68kパス名を設定 + const BYTE* GetHumanPath() const { ASSERT(this); return m_szHumanPath; } ///< Human68kパス名を取得 - BOOL Create(Human68k::fcb_t* pFcb, DWORD nHumanAttribute, BOOL bForce); - ///< ファイル作成 - BOOL Open(); - ///< ファイルオープン - BOOL Rewind(DWORD nOffset); - ///< ファイルシーク - DWORD Read(BYTE* pBuffer, DWORD nSize); - ///< ファイル読み込み - DWORD Write(const BYTE* pBuffer, DWORD nSize); - ///< ファイル書き込み - BOOL Truncate(); - ///< ファイル切り詰め - DWORD Seek(DWORD nOffset, DWORD nHumanSeek); - ///< ファイルシーク - BOOL TimeStamp(DWORD nHumanTime); - ///< ファイル時刻設定 - BOOL Close(); - ///< ファイルクローズ + BOOL Create(Human68k::fcb_t* pFcb, DWORD nHumanAttribute, BOOL bForce); ///< ファイル作成 + BOOL Open(); ///< ファイルオープン + BOOL Rewind(DWORD nOffset); ///< ファイルシーク + DWORD Read(BYTE* pBuffer, DWORD nSize); ///< ファイル読み込み + DWORD Write(const BYTE* pBuffer, DWORD nSize); ///< ファイル書き込み + BOOL Truncate(); ///< ファイル切り詰め + DWORD Seek(DWORD nOffset, DWORD nHumanSeek); ///< ファイルシーク + BOOL TimeStamp(DWORD nHumanTime); ///< ファイル時刻設定 + BOOL Close(); ///< ファイルクローズ private: - DWORD m_nKey; ///< Human68kのFCBバッファアドレス (0なら未使用) - BOOL m_bUpdate; ///< 更新フラグ -#ifndef BAREMETAL - FILE* m_pFile; ///< ホスト側のファイルオブジェクト - const char* m_pszMode; ///< ホスト側のファイルオープンモード -#else - FIL m_File; ///< ホスト側のファイルオブジェクト - BYTE m_Mode; ///< ホスト側のファイルオープンモード -#endif // BAREMETAL - bool m_bFlag; ///< ホスト側のファイルオープンフラグ + DWORD m_nKey; ///< Human68kのFCBバッファアドレス (0なら未使用) + BOOL m_bUpdate; ///< 更新フラグ + #ifndef BAREMETAL + FILE* m_pFile; ///< ホスト側のファイルオブジェクト + const char* m_pszMode; ///< ホスト側のファイルオープンモード + #else + FIL m_File; ///< ホスト側のファイルオブジェクト + BYTE m_Mode; ///< ホスト側のファイルオープンモード + #endif // BAREMETAL + bool m_bFlag; ///< ホスト側のファイルオープンフラグ BYTE m_szHumanPath[HUMAN68K_PATH_MAX]; - ///< Human68kのパス名 - TCHAR m_szFilename[FILEPATH_MAX]; ///< ホスト側のファイル名 + ///< Human68kのパス名 + TCHAR m_szFilename[FILEPATH_MAX]; ///< ホスト側のファイル名 }; //=========================================================================== @@ -849,31 +739,25 @@ private: //=========================================================================== class CHostFcbManager { public: -#ifdef _DEBUG + #ifdef _DEBUG // 基本ファンクション - ~CHostFcbManager(); - ///< デストラクタ final -#endif // _DEBUG - void Init(); - ///< 初期化 (ドライバ組込み時) - void Clean(); - ///< 解放 (起動・リセット時) + ~CHostFcbManager(); ///< デストラクタ final + #endif // _DEBUG + void Init(); ///< 初期化 (ドライバ組込み時) + void Clean(); ///< 解放 (起動・リセット時) - CHostFcb* Alloc(DWORD nKey); - ///< 確保 - CHostFcb* Search(DWORD nKey); - ///< 検索 - void Free(CHostFcb* p); - ///< 解放 + CHostFcb* Alloc(DWORD nKey); ///< 確保 + CHostFcb* Search(DWORD nKey); ///< 検索 + void Free(CHostFcb* p); ///< 解放 private: /// メモリ管理用 struct ring_t { - CRing r; ///< 円環 - CHostFcb f; ///< 実体 + CRing r; ///< 円環 + CHostFcb f; ///< 実体 }; - CRing m_cRing; ///< CHostFcb連結用 + CRing m_cRing; ///< CHostFcb連結用 }; //=========================================================================== @@ -887,57 +771,33 @@ class CHostDrv { public: // 基本ファンクション - CHostDrv(); - ///< デフォルトコンストラクタ - ~CHostDrv(); - ///< デストラクタ final - void Init(const TCHAR* szBase, DWORD nFlag); - ///< 初期化 (デバイス起動とロード) + CHostDrv(); ///< デフォルトコンストラクタ + ~CHostDrv(); ///< デストラクタ final + void Init(const TCHAR* szBase, DWORD nFlag); ///< 初期化 (デバイス起動とロード) - BOOL isWriteProtect() const { ASSERT(this); return m_bWriteProtect; } - ///< 書き込み禁止か? - BOOL isEnable() const { ASSERT(this); return m_bEnable; } - ///< アクセス可能か? - BOOL isMediaOffline(); - ///< メディアチェック - BYTE GetMediaByte() const; - ///< メディアバイトの取得 - DWORD GetStatus() const; - ///< ドライブ状態の取得 - void SetEnable(BOOL bEnable); - ///< メディア状態設定 - BOOL CheckMedia(); - ///< メディア交換チェック - void Update(); - ///< メディア状態更新 - void Eject(); - ///< イジェクト - void GetVolume(TCHAR* szLabel); - ///< ボリュームラベルの取得 - BOOL GetVolumeCache(TCHAR* szLabel) const; - ///< キャッシュからボリュームラベルを取得 - DWORD GetCapacity(Human68k::capacity_t* pCapacity); - ///< 容量の取得 - BOOL GetCapacityCache(Human68k::capacity_t* pCapacity) const; - ///< キャッシュから容量を取得 + BOOL isWriteProtect() const { ASSERT(this); return m_bWriteProtect; } ///< 書き込み禁止か? + BOOL isEnable() const { ASSERT(this); return m_bEnable; } ///< アクセス可能か? + BOOL isMediaOffline(); ///< メディアチェック + BYTE GetMediaByte() const; ///< メディアバイトの取得 + DWORD GetStatus() const; ///< ドライブ状態の取得 + void SetEnable(BOOL bEnable); ///< メディア状態設定 + BOOL CheckMedia(); ///< メディア交換チェック + void Update(); ///< メディア状態更新 + void Eject(); ///< イジェクト + void GetVolume(TCHAR* szLabel); ///< ボリュームラベルの取得 + BOOL GetVolumeCache(TCHAR* szLabel) const; ///< キャッシュからボリュームラベルを取得 + DWORD GetCapacity(Human68k::capacity_t* pCapacity); ///< 容量の取得 + BOOL GetCapacityCache(Human68k::capacity_t* pCapacity) const; ///< キャッシュから容量を取得 // キャッシュ操作 - void CleanCache(); - ///< 全てのキャッシュを更新する - void CleanCache(const BYTE* szHumanPath); - ///< 指定されたパスのキャッシュを更新する - void CleanCacheChild(const BYTE* szHumanPath); - ///< 指定されたパス以下のキャッシュを全て更新する - void DeleteCache(const BYTE* szHumanPath); - ///< 指定されたパスのキャッシュを削除する - CHostPath* FindCache(const BYTE* szHuman); - ///< 指定されたパスがキャッシュされているか検索する - CHostPath* CopyCache(CHostFiles* pFiles); - ///< キャッシュ情報を元に、ホスト側の名称を獲得する - CHostPath* MakeCache(CHostFiles* pFiles); - ///< ホスト側の名称の構築に必要な情報をすべて取得する - BOOL Find(CHostFiles* pFiles); - ///< ホスト側の名称を検索 (パス名+ファイル名(省略可)+属性) + void CleanCache(); ///< 全てのキャッシュを更新する + void CleanCache(const BYTE* szHumanPath); ///< 指定されたパスのキャッシュを更新する + void CleanCacheChild(const BYTE* szHumanPath); ///< 指定されたパス以下のキャッシュを全て更新する + void DeleteCache(const BYTE* szHumanPath); ///< 指定されたパスのキャッシュを削除する + CHostPath* FindCache(const BYTE* szHuman); ///< 指定されたパスがキャッシュされているか検索する + CHostPath* CopyCache(CHostFiles* pFiles); ///< キャッシュ情報を元に、ホスト側の名称を獲得する + CHostPath* MakeCache(CHostFiles* pFiles); ///< ホスト側の名称の構築に必要な情報をすべて取得する + BOOL Find(CHostFiles* pFiles); ///< ホスト側の名称を検索 (パス名+ファイル名(省略可)+属性) private: // パス名操作 @@ -951,17 +811,17 @@ private: /// メモリ管理用 struct ring_t { CRing r; ///< 円環 - CHostPath f; ///< 実体 + CHostPath f; ///< 実体 }; - BOOL m_bWriteProtect; ///< 書き込み禁止ならTRUE - BOOL m_bEnable; ///< メディアが利用可能ならTRUE - DWORD m_nRing; ///< パス名保持数 - CRing m_cRing; ///< CHostPath連結用 - Human68k::capacity_t m_capCache; ///< セクタ情報キャッシュ sectors == 0 なら未キャッシュ - BOOL m_bVolumeCache; ///< ボリュームラベル読み込み済みならTRUE - TCHAR m_szVolumeCache[24]; ///< ボリュームラベルキャッシュ - TCHAR m_szBase[FILEPATH_MAX]; ///< ベースパス + BOOL m_bWriteProtect; ///< 書き込み禁止ならTRUE + BOOL m_bEnable; ///< メディアが利用可能ならTRUE + DWORD m_nRing; ///< パス名保持数 + CRing m_cRing; ///< CHostPath連結用 + Human68k::capacity_t m_capCache; ///< セクタ情報キャッシュ sectors == 0 なら未キャッシュ + BOOL m_bVolumeCache; ///< ボリュームラベル読み込み済みならTRUE + TCHAR m_szVolumeCache[24]; ///< ボリュームラベルキャッシュ + TCHAR m_szBase[FILEPATH_MAX]; ///< ベースパス }; //=========================================================================== @@ -972,65 +832,43 @@ private: class CHostEntry { public: // 基本ファンクション - CHostEntry(); - ///< デフォルトコンストラクタ - ~CHostEntry(); - ///< デストラクタ final - void Init(); - ///< 初期化 (ドライバ組込み時) - void Clean(); - ///< 解放 (起動・リセット時) + CHostEntry(); ///< デフォルトコンストラクタ + ~CHostEntry(); ///< デストラクタ final + void Init(); ///< 初期化 (ドライバ組込み時) + void Clean(); ///< 解放 (起動・リセット時) // キャッシュ操作 - void CleanCache(); - ///< 全てのキャッシュを更新する - void CleanCache(DWORD nUnit); - ///< 指定されたユニットのキャッシュを更新する - void CleanCache(DWORD nUnit, const BYTE* szHumanPath); - ///< 指定されたパスのキャッシュを更新する - void CleanCacheChild(DWORD nUnit, const BYTE* szHumanPath); - ///< 指定されたパス以下のキャッシュを全て更新する - void DeleteCache(DWORD nUnit, const BYTE* szHumanPath); - ///< 指定されたパスのキャッシュを削除する - BOOL Find(DWORD nUnit, CHostFiles* pFiles); - ///< ホスト側の名称を検索 (パス名+ファイル名(省略可)+属性) - void ShellNotify(DWORD nEvent, const TCHAR* szPath); - ///< ホスト側ファイルシステム状態変化通知 + void CleanCache(); ///< 全てのキャッシュを更新する + void CleanCache(DWORD nUnit); ///< 指定されたユニットのキャッシュを更新する + void CleanCache(DWORD nUnit, const BYTE* szHumanPath); ///< 指定されたパスのキャッシュを更新する + void CleanCacheChild(DWORD nUnit, const BYTE* szHumanPath); ///< 指定されたパス以下のキャッシュを全て更新する + void DeleteCache(DWORD nUnit, const BYTE* szHumanPath); ///< 指定されたパスのキャッシュを削除する + BOOL Find(DWORD nUnit, CHostFiles* pFiles); ///< ホスト側の名称を検索 (パス名+ファイル名(省略可)+属性) + void ShellNotify(DWORD nEvent, const TCHAR* szPath); ///< ホスト側ファイルシステム状態変化通知 // ドライブオブジェクト操作 - void SetDrv(DWORD nUnit, CHostDrv* pDrv); - ///< ドライブ設定 - BOOL isWriteProtect(DWORD nUnit) const; - ///< 書き込み禁止か? - BOOL isEnable(DWORD nUnit) const; - ///< アクセス可能か? - BOOL isMediaOffline(DWORD nUnit); - ///< メディアチェック - BYTE GetMediaByte(DWORD nUnit) const; - ///< メディアバイトの取得 - DWORD GetStatus(DWORD nUnit) const; - ///< ドライブ状態の取得 - BOOL CheckMedia(DWORD nUnit); - ///< メディア交換チェック - void Eject(DWORD nUnit); - ///< イジェクト - void GetVolume(DWORD nUnit, TCHAR* szLabel); - ///< ボリュームラベルの取得 - BOOL GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const; - ///< キャッシュからボリュームラベルを取得 - DWORD GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity); - ///< 容量の取得 + void SetDrv(DWORD nUnit, CHostDrv* pDrv); ///< ドライブ設定 + BOOL isWriteProtect(DWORD nUnit) const; ///< 書き込み禁止か? + BOOL isEnable(DWORD nUnit) const; ///< アクセス可能か? + BOOL isMediaOffline(DWORD nUnit); ///< メディアチェック + BYTE GetMediaByte(DWORD nUnit) const; ///< メディアバイトの取得 + DWORD GetStatus(DWORD nUnit) const; ///< ドライブ状態の取得 + BOOL CheckMedia(DWORD nUnit); ///< メディア交換チェック + void Eject(DWORD nUnit); ///< イジェクト + void GetVolume(DWORD nUnit, TCHAR* szLabel); ///< ボリュームラベルの取得 + BOOL GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const; ///< キャッシュからボリュームラベルを取得 + DWORD GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity); ///< 容量の取得 BOOL GetCapacityCache(DWORD nUnit, Human68k::capacity_t* pCapacity) const; ///< キャッシュからクラスタサイズを取得 /// 定数 enum { - DriveMax = 10 ///< ドライブ最大候補数 + DriveMax = 10 ///< ドライブ最大候補数 }; private: - CHostDrv* m_pDrv[DriveMax]; ///< ホスト側ドライブオブジェクト - DWORD m_nTimeout; ///< 最後にタイムアウトチェックを行なった時刻 + CHostDrv* m_pDrv[DriveMax]; ///< ホスト側ドライブオブジェクト + DWORD m_nTimeout; ///< 最後にタイムアウトチェックを行なった時刻 }; //=========================================================================== @@ -1069,116 +907,87 @@ class CFileSys { public: // 基本ファンクション - CFileSys(); - ///< デフォルトコンストラクタ - virtual ~CFileSys() {}; - ///< デストラクタ + CFileSys(); ///< デフォルトコンストラクタ + virtual ~CFileSys() {}; ///< デストラクタ // 初期化・終了 - void Reset(); - ///< リセット (全クローズ) - void Init(); - ///< 初期化 (デバイス起動とロード) + void Reset(); ///< リセット (全クローズ) + void Init(); ///< 初期化 (デバイス起動とロード) // コマンドハンドラ - DWORD InitDevice(const Human68k::argument_t* pArgument); - ///< $40 - デバイス起動 - int CheckDir(DWORD nUnit, const Human68k::namests_t* pNamests); - ///< $41 - ディレクトリチェック - int MakeDir(DWORD nUnit, const Human68k::namests_t* pNamests); - ///< $42 - ディレクトリ作成 - int RemoveDir(DWORD nUnit, const Human68k::namests_t* pNamests); - ///< $43 - ディレクトリ削除 + DWORD InitDevice(const Human68k::argument_t* pArgument); ///< $40 - デバイス起動 + int CheckDir(DWORD nUnit, const Human68k::namests_t* pNamests); ///< $41 - ディレクトリチェック + int MakeDir(DWORD nUnit, const Human68k::namests_t* pNamests); ///< $42 - ディレクトリ作成 + int RemoveDir(DWORD nUnit, const Human68k::namests_t* pNamests); ///< $43 - ディレクトリ削除 int Rename(DWORD nUnit, const Human68k::namests_t* pNamests, const Human68k::namests_t* pNamestsNew); ///< $44 - ファイル名変更 - int Delete(DWORD nUnit, const Human68k::namests_t* pNamests); - ///< $45 - ファイル削除 + int Delete(DWORD nUnit, const Human68k::namests_t* pNamests); ///< $45 - ファイル削除 int Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD nHumanAttribute); ///< $46 - ファイル属性取得/設定 int Files(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests, Human68k::files_t* pFiles); ///< $47 - ファイル検索 - int NFiles(DWORD nUnit, DWORD nKey, Human68k::files_t* pFiles); - ///< $48 - ファイル次検索 + int NFiles(DWORD nUnit, DWORD nKey, Human68k::files_t* pFiles); ///< $48 - ファイル次検索 int Create(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests, Human68k::fcb_t* pFcb, DWORD nHumanAttribute, BOOL bForce); ///< $49 - ファイル作成 int Open(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests, Human68k::fcb_t* pFcb); ///< $4A - ファイルオープン - int Close(DWORD nUnit, DWORD nKey, Human68k::fcb_t* pFcb); - ///< $4B - ファイルクローズ + int Close(DWORD nUnit, DWORD nKey, Human68k::fcb_t* pFcb); ///< $4B - ファイルクローズ int Read(DWORD nKey, Human68k::fcb_t* pFcb, BYTE* pAddress, DWORD nSize); ///< $4C - ファイル読み込み int Write(DWORD nKey, Human68k::fcb_t* pFcb, const BYTE* pAddress, DWORD nSize); ///< $4D - ファイル書き込み - int Seek(DWORD nKey, Human68k::fcb_t* pFcb, DWORD nSeek, int nOffset); - ///< $4E - ファイルシーク + int Seek(DWORD nKey, Human68k::fcb_t* pFcb, DWORD nSeek, int nOffset); ///< $4E - ファイルシーク DWORD TimeStamp(DWORD nUnit, DWORD nKey, Human68k::fcb_t* pFcb, DWORD nHumanTime); ///< $4F - ファイル時刻取得/設定 - int GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity); - ///< $50 - 容量取得 - int CtrlDrive(DWORD nUnit, Human68k::ctrldrive_t* pCtrlDrive); - ///< $51 - ドライブ状態検査/制御 - int GetDPB(DWORD nUnit, Human68k::dpb_t* pDpb); - ///< $52 - DPB取得 - int DiskRead(DWORD nUnit, BYTE* pBuffer, DWORD nSector, DWORD nSize); - ///< $53 - セクタ読み込み - int DiskWrite(DWORD nUnit); - ///< $54 - セクタ書き込み - int Ioctrl(DWORD nUnit, DWORD nFunction, Human68k::ioctrl_t* pIoctrl); - ///< $55 - IOCTRL - int Flush(DWORD nUnit); - ///< $56 - フラッシュ - int CheckMedia(DWORD nUnit); - ///< $57 - メディア交換チェック - int Lock(DWORD nUnit); - ///< $58 - 排他制御 + int GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity); ///< $50 - 容量取得 + int CtrlDrive(DWORD nUnit, Human68k::ctrldrive_t* pCtrlDrive); ///< $51 - ドライブ状態検査/制御 + int GetDPB(DWORD nUnit, Human68k::dpb_t* pDpb); ///< $52 - DPB取得 + int DiskRead(DWORD nUnit, BYTE* pBuffer, DWORD nSector, DWORD nSize); ///< $53 - セクタ読み込み + int DiskWrite(DWORD nUnit); ///< $54 - セクタ書き込み + int Ioctrl(DWORD nUnit, DWORD nFunction, Human68k::ioctrl_t* pIoctrl); ///< $55 - IOCTRL + int Flush(DWORD nUnit); ///< $56 - フラッシュ + int CheckMedia(DWORD nUnit); ///< $57 - メディア交換チェック + int Lock(DWORD nUnit); ///< $58 - 排他制御 - void SetOption(DWORD nOption); - ///< オプション設定 - DWORD GetOption() const { ASSERT(this); return m_nOption; } - ///< オプション取得 - DWORD GetDefault() const { ASSERT(this); return m_nOptionDefault; } - ///< デフォルトオプション取得 - static DWORD GetFileOption() { return g_nOption; } - ///< ファイル名変換オプション取得 + void SetOption(DWORD nOption); ///< オプション設定 + DWORD GetOption() const { ASSERT(this); return m_nOption; } ///< オプション取得 + DWORD GetDefault() const { ASSERT(this); return m_nOptionDefault; } ///< デフォルトオプション取得 + static DWORD GetFileOption() { return g_nOption; } ///< ファイル名変換オプション取得 void ShellNotify(DWORD nEvent, const TCHAR* szPath) - { ASSERT(this); m_cEntry.ShellNotify(nEvent, szPath); } - ///< ホスト側ファイルシステム状態変化通知 + { ASSERT(this); m_cEntry.ShellNotify(nEvent, szPath); } ///< ホスト側ファイルシステム状態変化通知 /// 定数 enum { - DriveMax = CHostEntry::DriveMax ///< ドライブ最大候補数 + DriveMax = CHostEntry::DriveMax ///< ドライブ最大候補数 }; private: // 内部補助用 - void InitOption(const Human68k::argument_t* pArgument); - ///< オプション初期化 - BOOL FilesVolume(DWORD nUnit, Human68k::files_t* pFiles); - ///< ボリュームラベル取得 + void InitOption(const Human68k::argument_t* pArgument); ///< オプション初期化 + BOOL FilesVolume(DWORD nUnit, Human68k::files_t* pFiles); ///< ボリュームラベル取得 - DWORD m_nUnits; ///< 現在のドライブオブジェクト数 (レジューム毎に変化) + DWORD m_nUnits; ///< 現在のドライブオブジェクト数 (レジューム毎に変化) - DWORD m_nOption; ///< 現在の動作フラグ - DWORD m_nOptionDefault; ///< リセット時の動作フラグ + DWORD m_nOption; ///< 現在の動作フラグ + DWORD m_nOptionDefault; ///< リセット時の動作フラグ - DWORD m_nDrives; ///< ベースパス状態復元用の候補数 (0なら毎回スキャン) + DWORD m_nDrives; ///< ベースパス状態復元用の候補数 (0なら毎回スキャン) - DWORD m_nKernel; ///< カーネルチェック用カウンタ - DWORD m_nKernelSearch; ///< NULデバイスの先頭アドレス + DWORD m_nKernel; ///< カーネルチェック用カウンタ + DWORD m_nKernelSearch; ///< NULデバイスの先頭アドレス - DWORD m_nHostSectorCount; ///< 擬似セクタ番号 + DWORD m_nHostSectorCount; ///< 擬似セクタ番号 - CHostFilesManager m_cFiles; ///< ファイル検索領域 - CHostFcbManager m_cFcb; ///< FCB操作領域 - CHostEntry m_cEntry; ///< ドライブオブジェクトとディレクトリエントリ + CHostFilesManager m_cFiles; ///< ファイル検索領域 + CHostFcbManager m_cFcb; ///< FCB操作領域 + CHostEntry m_cEntry; ///< ドライブオブジェクトとディレクトリエントリ DWORD m_nHostSectorBuffer[XM6_HOST_PSEUDO_CLUSTER_MAX]; ///< 擬似セクタの指すファイル実体 - DWORD m_nFlag[DriveMax]; ///< ベースパス状態復元用の動作フラグ候補 - TCHAR m_szBase[DriveMax][FILEPATH_MAX]; - ///< ベースパス状態復元用の候補 - static DWORD g_nOption; ///< ファイル名変換フラグ + DWORD m_nFlag[DriveMax]; ///< ベースパス状態復元用の動作フラグ候補 + TCHAR m_szBase[DriveMax][FILEPATH_MAX]; ///< ベースパス状態復元用の候補 + static DWORD g_nOption; ///< ファイル名変換フラグ }; #endif // cfilesystem_h diff --git a/src/raspberrypi/devices/ctapdriver.h b/src/raspberrypi/devices/ctapdriver.h index 68dffe66..9122a2d6 100644 --- a/src/raspberrypi/devices/ctapdriver.h +++ b/src/raspberrypi/devices/ctapdriver.h @@ -28,26 +28,17 @@ class CTapDriver { public: // Basic Functionality - CTapDriver(); - // Constructor - BOOL FASTCALL Init(); - // Initilization - void FASTCALL Cleanup(); - // Cleanup - void FASTCALL GetMacAddr(BYTE *mac); - // Get Mac Address - int FASTCALL Rx(BYTE *buf); - // Receive - int FASTCALL Tx(BYTE *buf, int len); - // Send + CTapDriver(); // Constructor + BOOL FASTCALL Init(); // Initilization + void FASTCALL Cleanup(); // Cleanup + void FASTCALL GetMacAddr(BYTE *mac); // Get Mac Address + int FASTCALL Rx(BYTE *buf); // Receive + int FASTCALL Tx(BYTE *buf, int len); // Send private: - BYTE m_MacAddr[6]; - // MAC Address - BOOL m_bTxValid; - // Send Valid Flag - int m_hTAP; - // File handle + BYTE m_MacAddr[6]; // MAC Address + BOOL m_bTxValid; // Send Valid Flag + int m_hTAP; // File handle }; #endif // ctapdriver_h diff --git a/src/raspberrypi/devices/disk.cpp b/src/raspberrypi/devices/disk.cpp index a05f27ac..f608e7e3 100644 --- a/src/raspberrypi/devices/disk.cpp +++ b/src/raspberrypi/devices/disk.cpp @@ -11,7 +11,7 @@ // // Imported sava's Anex86/T98Next image and MO format support patch. // Imported NetBSD support and some optimisation patch by Rin Okuyama. -// Comments translated to english by akuker. +// Comments translated to english by akuker. // // [ Disk ] // @@ -161,11 +161,11 @@ BOOL FASTCALL DiskTrack::Load(const Filepath& path) ASSERT((dt.sectors > 0) && (dt.sectors <= 0x100)); if (dt.buffer == NULL) { -#if defined(RASCSI) && !defined(BAREMETAL) + #if defined(RASCSI) && !defined(BAREMETAL) posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512); -#else + #else dt.buffer = (BYTE *)malloc(length * sizeof(BYTE)); -#endif // RASCSI && !BAREMETAL + #endif // RASCSI && !BAREMETAL dt.length = length; } @@ -176,11 +176,11 @@ BOOL FASTCALL DiskTrack::Load(const Filepath& path) // Reallocate if the buffer length is different if (dt.length != (DWORD)length) { free(dt.buffer); -#if defined(RASCSI) && !defined(BAREMETAL) + #if defined(RASCSI) && !defined(BAREMETAL) posix_memalign((void **)&dt.buffer, 512, ((length + 511) / 512) * 512); -#else + #else dt.buffer = (BYTE *)malloc(length * sizeof(BYTE)); -#endif // RASCSI && !BAREMETAL + #endif // RASCSI && !BAREMETAL dt.length = length; } @@ -205,11 +205,11 @@ BOOL FASTCALL DiskTrack::Load(const Filepath& path) memset(dt.changemap, 0x00, dt.sectors * sizeof(BOOL)); // Read from File -#if defined(RASCSI) && !defined(BAREMETAL) + #if defined(RASCSI) && !defined(BAREMETAL) if (!fio.OpenDIO(path, Fileio::ReadOnly)) { -#else + #else if (!fio.Open(path, Fileio::ReadOnly)) { -#endif // RASCSI && !BAREMETAL + #endif // RASCSI && !BAREMETAL return FALSE; } if (dt.raw) { @@ -1653,7 +1653,7 @@ int FASTCALL Disk::AddFormat(BOOL change, BYTE *buf) buf[1] = 0x16; // Show the number of bytes in the physical sector as changeable - // (though it cannot be changed in practice) + // (though it cannot be changed in practice) if (change) { buf[0xc] = 0xff; buf[0xd] = 0xff; @@ -1815,7 +1815,7 @@ int FASTCALL Disk::AddCDDA(BOOL change, BYTE *buf) } // Audio waits for operation completion and allows - // PLAY across multiple tracks + // PLAY across multiple tracks return 16; } diff --git a/src/raspberrypi/devices/disk.h b/src/raspberrypi/devices/disk.h index 725880fb..e2c7ef1d 100644 --- a/src/raspberrypi/devices/disk.h +++ b/src/raspberrypi/devices/disk.h @@ -8,8 +8,8 @@ // XM6i // Copyright (C) 2010-2015 isaki@NetBSD.org // -// Imported sava's Anex86/T98Next image and MO format support patch. -// Comments translated to english by akuker. +// Imported sava's Anex86/T98Next image and MO format support patch. +// Comments translated to english by akuker. // // [ Disk ] // @@ -62,11 +62,11 @@ #ifdef RASCSI -#define BENDER_SIGNATURE "RaSCSI" +#define BENDER_SIGNATURE "RaSCSI" // The following line was to mimic Apple's CDROM ID // #define BENDER_SIGNATURE "SONY " #else -#define BENDER_SIGNATURE "XM6" +#define BENDER_SIGNATURE "XM6" #endif //=========================================================================== @@ -79,49 +79,38 @@ class DiskTrack public: // Internal data definition typedef struct { - int track; // Track Number - int size; // Sector Size(8 or 9) - int sectors; // Number of sectors(<=0x100) - DWORD length; // Data buffer length - BYTE *buffer; // Data buffer - BOOL init; // Is it initilized? - BOOL changed; // Changed flag - DWORD maplen; // Changed map length - BOOL *changemap; // Changed map - BOOL raw; // RAW mode flag - off64_t imgoffset; // Offset to actual data + int track; // Track Number + int size; // Sector Size(8 or 9) + int sectors; // Number of sectors(<=0x100) + DWORD length; // Data buffer length + BYTE *buffer; // Data buffer + BOOL init; // Is it initilized? + BOOL changed; // Changed flag + DWORD maplen; // Changed map length + BOOL *changemap; // Changed map + BOOL raw; // RAW mode flag + off64_t imgoffset; // Offset to actual data } disktrk_t; public: // Basic Functions - DiskTrack(); - // Constructor - virtual ~DiskTrack(); - // Destructor - void FASTCALL Init(int track, int size, int sectors, BOOL raw = FALSE, - off64_t imgoff = 0); - // Initialization - BOOL FASTCALL Load(const Filepath& path); - // Load - BOOL FASTCALL Save(const Filepath& path); - // Save + DiskTrack(); // Constructor + virtual ~DiskTrack(); // Destructor + void FASTCALL Init(int track, int size, int sectors, BOOL raw = FALSE, off64_t imgoff = 0);// Initialization + BOOL FASTCALL Load(const Filepath& path); // Load + BOOL FASTCALL Save(const Filepath& path); // Save // Read / Write - BOOL FASTCALL Read(BYTE *buf, int sec) const; - // Sector Read - BOOL FASTCALL Write(const BYTE *buf, int sec); - // Sector Write + BOOL FASTCALL Read(BYTE *buf, int sec) const; // Sector Read + BOOL FASTCALL Write(const BYTE *buf, int sec); // Sector Write // Other - int FASTCALL GetTrack() const { return dt.track; } - // Get track - BOOL FASTCALL IsChanged() const { return dt.changed; } - // Changed flag check + int FASTCALL GetTrack() const { return dt.track; } // Get track + BOOL FASTCALL IsChanged() const { return dt.changed; } // Changed flag check private: // Internal data - disktrk_t dt; - // Internal data + disktrk_t dt; // Internal data }; //=========================================================================== @@ -134,61 +123,42 @@ class DiskCache public: // Internal data definition typedef struct { - DiskTrack *disktrk; // Disk Track - DWORD serial; // Serial + DiskTrack *disktrk; // Disk Track + DWORD serial; // Serial } cache_t; // Number of caches enum { - CacheMax = 16 // Number of tracks to cache + CacheMax = 16 // Number of tracks to cache }; public: // Basic Functions - DiskCache(const Filepath& path, int size, int blocks, - off64_t imgoff = 0); - // Constructor - virtual ~DiskCache(); - // Destructor - void FASTCALL SetRawMode(BOOL raw); - // CD-ROM raw mode setting + DiskCache(const Filepath& path, int size, int blocks,off64_t imgoff = 0);// Constructor + virtual ~DiskCache(); // Destructor + void FASTCALL SetRawMode(BOOL raw); // CD-ROM raw mode setting // Access - BOOL FASTCALL Save(); - // Save and release all - BOOL FASTCALL Read(BYTE *buf, int block); - // Sector Read - BOOL FASTCALL Write(const BYTE *buf, int block); - // Sector Write - BOOL FASTCALL GetCache(int index, int& track, DWORD& serial) const; - // Get cache information + BOOL FASTCALL Save(); // Save and release all + BOOL FASTCALL Read(BYTE *buf, int block); // Sector Read + BOOL FASTCALL Write(const BYTE *buf, int block); // Sector Write + BOOL FASTCALL GetCache(int index, int& track, DWORD& serial) const; // Get cache information private: // Internal Management - void FASTCALL Clear(); - // Clear all tracks - DiskTrack* FASTCALL Assign(int track); - // Load track - BOOL FASTCALL Load(int index, int track, DiskTrack *disktrk = NULL); - // Load track - void FASTCALL Update(); - // Update serial number + void FASTCALL Clear(); // Clear all tracks + DiskTrack* FASTCALL Assign(int track); // Load track + BOOL FASTCALL Load(int index, int track, DiskTrack *disktrk = NULL); // Load track + void FASTCALL Update(); // Update serial number // Internal data - cache_t cache[CacheMax]; - // Cache management - DWORD serial; - // Last serial number - Filepath sec_path; - // Path - int sec_size; - // Sector size (8 or 9 or 11) - int sec_blocks; - // Blocks per sector - BOOL cd_raw; - // CD-ROM RAW mode - off64_t imgoffset; - // Offset to actual data + cache_t cache[CacheMax]; // Cache management + DWORD serial; // Last serial number + Filepath sec_path; // Path + int sec_size; // Sector size (8 or 9 or 11) + int sec_blocks; // Blocks per sector + BOOL cd_raw; // CD-ROM RAW mode + off64_t imgoffset; // Offset to actual data }; //=========================================================================== @@ -201,168 +171,104 @@ class Disk public: // Internal data structure typedef struct { - DWORD id; // Media ID - BOOL ready; // Valid Disk - BOOL writep; // Write protected - BOOL readonly; // Read only - BOOL removable; // Removable - BOOL lock; // Locked - BOOL attn; // Attention - BOOL reset; // Reset - int size; // Sector Size - DWORD blocks; // Total number of sectors - DWORD lun; // LUN - DWORD code; // Status code - DiskCache *dcache; // Disk cache - off64_t imgoffset; // Offset to actual data + DWORD id; // Media ID + BOOL ready; // Valid Disk + BOOL writep; // Write protected + BOOL readonly; // Read only + BOOL removable; // Removable + BOOL lock; // Locked + BOOL attn; // Attention + BOOL reset; // Reset + int size; // Sector Size + DWORD blocks; // Total number of sectors + DWORD lun; // LUN + DWORD code; // Status code + DiskCache *dcache; // Disk cache + off64_t imgoffset; // Offset to actual data } disk_t; public: // Basic Functions - Disk(); - // Constructor - virtual ~Disk(); - // Destructor - virtual void FASTCALL Reset(); - // Device Reset -#ifndef RASCSI - virtual BOOL FASTCALL Save(Fileio *fio, int ver); - // Save - virtual BOOL FASTCALL Load(Fileio *fio, int ver); - // Load -#endif // RASCSI + Disk(); // Constructor + virtual ~Disk(); // Destructor + virtual void FASTCALL Reset(); // Device Reset + #ifndef RASCSI + virtual BOOL FASTCALL Save(Fileio *fio, int ver); // Save + virtual BOOL FASTCALL Load(Fileio *fio, int ver); // Load + #endif // RASCSI // ID - DWORD FASTCALL GetID() const { return disk.id; } - // Get media ID - BOOL FASTCALL IsNULL() const; - // NULL check - BOOL FASTCALL IsSASI() const; - // SASI Check - BOOL FASTCALL IsSCSI() const; - // SASI Check + DWORD FASTCALL GetID() const { return disk.id; } // Get media ID + BOOL FASTCALL IsNULL() const; // NULL check + BOOL FASTCALL IsSASI() const; // SASI Check + BOOL FASTCALL IsSCSI() const; // SASI Check // Media Operations - virtual BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); - // Open - void FASTCALL GetPath(Filepath& path) const; - // Get the path - void FASTCALL Eject(BOOL force); - // Eject - BOOL FASTCALL IsReady() const { return disk.ready; } - // Ready check - void FASTCALL WriteP(BOOL flag); - // Set Write Protect flag - BOOL FASTCALL IsWriteP() const { return disk.writep; } - // Get write protect flag - BOOL FASTCALL IsReadOnly() const { return disk.readonly; } - // Get read only flag - BOOL FASTCALL IsRemovable() const { return disk.removable; } - // Get is removable flag - 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 + virtual BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); // Open + void FASTCALL GetPath(Filepath& path) const; // Get the path + void FASTCALL Eject(BOOL force); // Eject + BOOL FASTCALL IsReady() const { return disk.ready; } // Ready check + void FASTCALL WriteP(BOOL flag); // Set Write Protect flag + BOOL FASTCALL IsWriteP() const { return disk.writep; } // Get write protect flag + BOOL FASTCALL IsReadOnly() const { return disk.readonly; } // Get read only flag + BOOL FASTCALL IsRemovable() const { return disk.removable; } // Get is removable flag + 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 - DWORD FASTCALL GetLUN() { return disk.lun; } - // LUN get + void FASTCALL SetLUN(DWORD lun) { disk.lun = lun; } // LUN set + DWORD FASTCALL GetLUN() { return disk.lun; } // LUN get + // commands - virtual int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); - // INQUIRY command - virtual int FASTCALL RequestSense(const DWORD *cdb, BYTE *buf); - // REQUEST SENSE command - int FASTCALL SelectCheck(const DWORD *cdb); - // SELECT check - int FASTCALL SelectCheck10(const DWORD *cdb); - // SELECT(10) check - virtual BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length); - // MODE SELECT command - virtual int FASTCALL ModeSense(const DWORD *cdb, BYTE *buf); - // MODE SENSE command - virtual int FASTCALL ModeSense10(const DWORD *cdb, BYTE *buf); - // MODE SENSE(10) command - int FASTCALL ReadDefectData10(const DWORD *cdb, BYTE *buf); - // READ DEFECT DATA(10) command - virtual BOOL FASTCALL TestUnitReady(const DWORD *cdb); - // TEST UNIT READY command - BOOL FASTCALL Rezero(const DWORD *cdb); - // REZERO command - BOOL FASTCALL Format(const DWORD *cdb); - // FORMAT UNIT command - BOOL FASTCALL Reassign(const DWORD *cdb); - // REASSIGN UNIT command - virtual int FASTCALL Read(BYTE *buf, DWORD block); - // READ command - int FASTCALL WriteCheck(DWORD block); - // WRITE check - BOOL FASTCALL Write(const BYTE *buf, DWORD block); - // WRITE command - BOOL FASTCALL Seek(const DWORD *cdb); - // SEEK command - BOOL FASTCALL Assign(const DWORD *cdb); - // ASSIGN command - BOOL FASTCALL Specify(const DWORD *cdb); - // SPECIFY command - BOOL FASTCALL StartStop(const DWORD *cdb); - // START STOP UNIT command - BOOL FASTCALL SendDiag(const DWORD *cdb); - // SEND DIAGNOSTIC command - BOOL FASTCALL Removal(const DWORD *cdb); - // PREVENT/ALLOW MEDIUM REMOVAL command - int FASTCALL ReadCapacity(const DWORD *cdb, BYTE *buf); - // READ CAPACITY command - BOOL FASTCALL Verify(const DWORD *cdb); - // VERIFY command - virtual int FASTCALL ReadToc(const DWORD *cdb, BYTE *buf); - // READ TOC command - 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() { disk.code = DISK_INVALIDCMD; } - // Unsupported command + virtual int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);// INQUIRY command + virtual int FASTCALL RequestSense(const DWORD *cdb, BYTE *buf); // REQUEST SENSE command + int FASTCALL SelectCheck(const DWORD *cdb); // SELECT check + int FASTCALL SelectCheck10(const DWORD *cdb); // SELECT(10) check + virtual BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length);// MODE SELECT command + virtual int FASTCALL ModeSense(const DWORD *cdb, BYTE *buf); // MODE SENSE command + virtual int FASTCALL ModeSense10(const DWORD *cdb, BYTE *buf); // MODE SENSE(10) command + int FASTCALL ReadDefectData10(const DWORD *cdb, BYTE *buf); // READ DEFECT DATA(10) command + virtual BOOL FASTCALL TestUnitReady(const DWORD *cdb); // TEST UNIT READY command + BOOL FASTCALL Rezero(const DWORD *cdb); // REZERO command + BOOL FASTCALL Format(const DWORD *cdb); // FORMAT UNIT command + BOOL FASTCALL Reassign(const DWORD *cdb); // REASSIGN UNIT command + virtual int FASTCALL Read(BYTE *buf, DWORD block); // READ command + int FASTCALL WriteCheck(DWORD block); // WRITE check + BOOL FASTCALL Write(const BYTE *buf, DWORD block); // WRITE command + BOOL FASTCALL Seek(const DWORD *cdb); // SEEK command + BOOL FASTCALL Assign(const DWORD *cdb); // ASSIGN command + BOOL FASTCALL Specify(const DWORD *cdb); // SPECIFY command + BOOL FASTCALL StartStop(const DWORD *cdb); // START STOP UNIT command + BOOL FASTCALL SendDiag(const DWORD *cdb); // SEND DIAGNOSTIC command + BOOL FASTCALL Removal(const DWORD *cdb); // PREVENT/ALLOW MEDIUM REMOVAL command + int FASTCALL ReadCapacity(const DWORD *cdb, BYTE *buf); // READ CAPACITY command + BOOL FASTCALL Verify(const DWORD *cdb); // VERIFY command + virtual int FASTCALL ReadToc(const DWORD *cdb, BYTE *buf); // READ TOC command + 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() { disk.code = DISK_INVALIDCMD; } // Unsupported command // Other - BOOL IsCacheWB() { return cache_wb; } - // Get cache writeback mode - void SetCacheWB(BOOL enable) { cache_wb = enable; } - // Set cache writeback mode + BOOL IsCacheWB() { return cache_wb; } // Get cache writeback mode + void SetCacheWB(BOOL enable) { cache_wb = enable; } // Set cache writeback mode protected: // Internal processing - virtual int FASTCALL AddError(BOOL change, BYTE *buf); - // Add error - virtual int FASTCALL AddFormat(BOOL change, BYTE *buf); - // Add format - virtual int FASTCALL AddDrive(BOOL change, BYTE *buf); - // Add drive - int FASTCALL AddOpt(BOOL change, BYTE *buf); - // Add optical - int FASTCALL AddCache(BOOL change, BYTE *buf); - // Add cache - int FASTCALL AddCDROM(BOOL change, BYTE *buf); - // Add CD-ROM - int FASTCALL AddCDDA(BOOL change, BYTE *buf); - // Add CD_DA - virtual int FASTCALL AddVendor(int page, BOOL change, BYTE *buf); - // Add vendor special info - BOOL FASTCALL CheckReady(); - // Check if ready + virtual int FASTCALL AddError(BOOL change, BYTE *buf); // Add error + virtual int FASTCALL AddFormat(BOOL change, BYTE *buf); // Add format + virtual int FASTCALL AddDrive(BOOL change, BYTE *buf); // Add drive + int FASTCALL AddOpt(BOOL change, BYTE *buf); // Add optical + int FASTCALL AddCache(BOOL change, BYTE *buf); // Add cache + int FASTCALL AddCDROM(BOOL change, BYTE *buf); // Add CD-ROM + int FASTCALL AddCDDA(BOOL change, BYTE *buf); // Add CD_DA + virtual int FASTCALL AddVendor(int page, BOOL change, BYTE *buf); // Add vendor special info + BOOL FASTCALL CheckReady(); // Check if ready // Internal data - disk_t disk; - // Internal disk data - Filepath diskpath; - // File path (for GetPath) - BOOL cache_wb; - // Cache mode + disk_t disk; // Internal disk data + Filepath diskpath; // File path (for GetPath) + BOOL cache_wb; // Cache mode }; diff --git a/src/raspberrypi/devices/sasihd.cpp b/src/raspberrypi/devices/sasihd.cpp index ba0a8cb4..e571747c 100644 --- a/src/raspberrypi/devices/sasihd.cpp +++ b/src/raspberrypi/devices/sasihd.cpp @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SASI hard disk ] +// [ SASI hard disk ] // //--------------------------------------------------------------------------- #include "sasihd.h" @@ -73,7 +73,7 @@ BOOL FASTCALL SASIHD::Open(const Filepath& path, BOOL /*attn*/) size = fio.GetFileSize(); fio.Close(); -#if defined(USE_MZ1F23_1024_SUPPORT) + #if defined(USE_MZ1F23_1024_SUPPORT) // MZ-2500/MZ-2800用 MZ-1F23(SASI 20M/セクタサイズ1024)専用 // 20M(22437888 BS=1024 C=21912) if (size == 0x1566000) { @@ -84,9 +84,9 @@ BOOL FASTCALL SASIHD::Open(const Filepath& path, BOOL /*attn*/) // Call the base class return Disk::Open(path); } -#endif // USE_MZ1F23_1024_SUPPORT + #endif // USE_MZ1F23_1024_SUPPORT -#if defined(REMOVE_FIXED_SASIHD_SIZE) + #if defined(REMOVE_FIXED_SASIHD_SIZE) // 256バイト単位であること if (size & 0xff) { return FALSE; @@ -101,7 +101,7 @@ BOOL FASTCALL SASIHD::Open(const Filepath& path, BOOL /*attn*/) if (size > 512 * 1024 * 1024) { return FALSE; } -#else + #else // 10MB, 20MB, 40MBのみ switch (size) { // 10MB(10441728 BS=256 C=40788) @@ -120,7 +120,7 @@ BOOL FASTCALL SASIHD::Open(const Filepath& path, BOOL /*attn*/) default: return FALSE; } -#endif // REMOVE_FIXED_SASIHD_SIZE + #endif // REMOVE_FIXED_SASIHD_SIZE // セクタサイズとブロック数 disk.size = 8; diff --git a/src/raspberrypi/devices/sasihd.h b/src/raspberrypi/devices/sasihd.h index eb305d28..a031c7cc 100644 --- a/src/raspberrypi/devices/sasihd.h +++ b/src/raspberrypi/devices/sasihd.h @@ -5,10 +5,10 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // // [ SASI hard disk ] // @@ -28,13 +28,10 @@ class SASIHD : public Disk { public: // Basic Functions - SASIHD(); - // Constructor - void FASTCALL Reset(); - // Reset - BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); - // Open + SASIHD(); // Constructor + void FASTCALL Reset(); // Reset + BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); // Open + // commands - int FASTCALL RequestSense(const DWORD *cdb, BYTE *buf); - // REQUEST SENSE command + int FASTCALL RequestSense(const DWORD *cdb, BYTE *buf); // REQUEST SENSE command }; \ No newline at end of file diff --git a/src/raspberrypi/devices/scsi_host_bridge.cpp b/src/raspberrypi/devices/scsi_host_bridge.cpp index 520c5c46..2cdc72fd 100644 --- a/src/raspberrypi/devices/scsi_host_bridge.cpp +++ b/src/raspberrypi/devices/scsi_host_bridge.cpp @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI Host Bridge for the Sharp X68000 ] +// [ SCSI Host Bridge for the Sharp X68000 ] // // Note: This requires a special driver on the host system and will only // work with the Sharp X68000 operating system. @@ -37,7 +37,7 @@ SCSIBR::SCSIBR() : Disk() // Host Bridge disk.id = MAKEID('S', 'C', 'B', 'R'); -#if defined(RASCSI) && defined(__linux__) && !defined(BAREMETAL) + #if defined(RASCSI) && defined(__linux__) && !defined(BAREMETAL) // TAP Driver Generation tap = new CTapDriver(); m_bTapEnable = tap->Init(); @@ -51,7 +51,7 @@ SCSIBR::SCSIBR() : Disk() // Packet reception flag OFF packet_enable = FALSE; -#endif // RASCSI && !BAREMETAL + #endif // RASCSI && !BAREMETAL // Create host file system fs = new CFileSys(); @@ -65,13 +65,13 @@ SCSIBR::SCSIBR() : Disk() //--------------------------------------------------------------------------- SCSIBR::~SCSIBR() { -#if defined(RASCSI) && !defined(BAREMETAL) + #if defined(RASCSI) && !defined(BAREMETAL) // TAP driver release if (tap) { tap->Cleanup(); delete tap; } -#endif // RASCSI && !BAREMETAL + #endif // RASCSI && !BAREMETAL // Release host file system if (fs) { @@ -136,12 +136,12 @@ int FASTCALL SCSIBR::Inquiry( // Optional function valid flag buf[36] = '0'; -#if defined(RASCSI) && !defined(BAREMETAL) + #if defined(RASCSI) && !defined(BAREMETAL) // TAP Enable if (m_bTapEnable) { buf[37] = '1'; } -#endif // RASCSI && !BAREMETAL + #endif // RASCSI && !BAREMETAL // CFileSys Enable buf[38] = '1'; @@ -182,27 +182,27 @@ int FASTCALL SCSIBR::GetMessage10(const DWORD *cdb, BYTE *buf) { int type; int phase; -#if defined(RASCSI) && !defined(BAREMETAL) + #if defined(RASCSI) && !defined(BAREMETAL) int func; int total_len; int i; -#endif // RASCSI && !BAREMETAL + #endif // RASCSI && !BAREMETAL ASSERT(this); // Type type = cdb[2]; -#if defined(RASCSI) && !defined(BAREMETAL) + #if defined(RASCSI) && !defined(BAREMETAL) // Function number func = cdb[3]; -#endif // RASCSI && !BAREMETAL + #endif // RASCSI && !BAREMETAL // Phase phase = cdb[9]; switch (type) { -#if defined(RASCSI) && !defined(BAREMETAL) + #if defined(RASCSI) && !defined(BAREMETAL) case 1: // Ethernet // Do not process if TAP is invalid if (!m_bTapEnable) { @@ -251,7 +251,7 @@ int FASTCALL SCSIBR::GetMessage10(const DWORD *cdb, BYTE *buf) return total_len; } break; -#endif // RASCSI && !BAREMETAL + #endif // RASCSI && !BAREMETAL case 2: // Host Drive switch (phase) { @@ -305,7 +305,7 @@ BOOL FASTCALL SCSIBR::SendMessage10(const DWORD *cdb, BYTE *buf) len |= cdb[8]; switch (type) { -#if defined(RASCSI) && !defined(BAREMETAL) + #if defined(RASCSI) && !defined(BAREMETAL) case 1: // Ethernet // Do not process if TAP is invalid if (!m_bTapEnable) { @@ -322,7 +322,7 @@ BOOL FASTCALL SCSIBR::SendMessage10(const DWORD *cdb, BYTE *buf) return TRUE; } break; -#endif // RASCSI && !BAREMETAL + #endif // RASCSI && !BAREMETAL case 2: // Host drive switch (phase) { @@ -1462,30 +1462,30 @@ void FASTCALL SCSIBR::WriteFs(int func, BYTE *buf) func &= 0x1f; switch (func) { case 0x00: return FS_InitDevice(buf); // $40 - start device - case 0x01: return FS_CheckDir(buf); // $41 - directory check - case 0x02: return FS_MakeDir(buf); // $42 - create directory + case 0x01: return FS_CheckDir(buf); // $41 - directory check + case 0x02: return FS_MakeDir(buf); // $42 - create directory case 0x03: return FS_RemoveDir(buf); // $43 - remove directory - case 0x04: return FS_Rename(buf); // $44 - change file name - case 0x05: return FS_Delete(buf); // $45 - delete file + case 0x04: return FS_Rename(buf); // $44 - change file name + case 0x05: return FS_Delete(buf); // $45 - delete file case 0x06: return FS_Attribute(buf); // $46 - Get/set file attribute - case 0x07: return FS_Files(buf); // $47 - file search - case 0x08: return FS_NFiles(buf); // $48 - next file search - case 0x09: return FS_Create(buf); // $49 - create file - case 0x0A: return FS_Open(buf); // $4A - File open - case 0x0B: return FS_Close(buf); // $4B - File close - case 0x0C: return FS_Read(buf); // $4C - read file - case 0x0D: return FS_Write(buf); // $4D - write file - case 0x0E: return FS_Seek(buf); // $4E - File seek + case 0x07: return FS_Files(buf); // $47 - file search + case 0x08: return FS_NFiles(buf); // $48 - next file search + case 0x09: return FS_Create(buf); // $49 - create file + case 0x0A: return FS_Open(buf); // $4A - File open + case 0x0B: return FS_Close(buf); // $4B - File close + case 0x0C: return FS_Read(buf); // $4C - read file + case 0x0D: return FS_Write(buf); // $4D - write file + case 0x0E: return FS_Seek(buf); // $4E - File seek case 0x0F: return FS_TimeStamp(buf); // $4F - Get/set file modification time case 0x10: return FS_GetCapacity(buf); // $50 - get capacity case 0x11: return FS_CtrlDrive(buf); // $51 - Drive control/state check - case 0x12: return FS_GetDPB(buf); // $52 - Get DPB - case 0x13: return FS_DiskRead(buf); // $53 - read sector + case 0x12: return FS_GetDPB(buf); // $52 - Get DPB + case 0x13: return FS_DiskRead(buf); // $53 - read sector case 0x14: return FS_DiskWrite(buf); // $54 - write sector - case 0x15: return FS_Ioctrl(buf); // $55 - IOCTRL - case 0x16: return FS_Flush(buf); // $56 - flush + case 0x15: return FS_Ioctrl(buf); // $55 - IOCTRL + case 0x16: return FS_Flush(buf); // $56 - flush case 0x17: return FS_CheckMedia(buf); // $57 - check media exchange - case 0x18: return FS_Lock(buf); // $58 - exclusive control + case 0x18: return FS_Lock(buf); // $58 - exclusive control } } diff --git a/src/raspberrypi/devices/scsi_host_bridge.h b/src/raspberrypi/devices/scsi_host_bridge.h index e79e933f..a5ef6871 100644 --- a/src/raspberrypi/devices/scsi_host_bridge.h +++ b/src/raspberrypi/devices/scsi_host_bridge.h @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI Host Bridge for the Sharp X68000 ] +// [ SCSI Host Bridge for the Sharp X68000 ] // // Note: This requires a special driver on the host system and will only // work with the Sharp X68000 operating system. @@ -34,120 +34,68 @@ class SCSIBR : public Disk { public: // Basic Functions - SCSIBR(); - // Constructor - virtual ~SCSIBR(); - // Destructor + SCSIBR(); // Constructor + virtual ~SCSIBR(); // Destructor // commands - int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); - // INQUIRY command - BOOL FASTCALL TestUnitReady(const DWORD *cdb); - // TEST UNIT READY command - int FASTCALL GetMessage10(const DWORD *cdb, BYTE *buf); - // GET MESSAGE10 command - BOOL FASTCALL SendMessage10(const DWORD *cdb, BYTE *buf); - // SEND MESSAGE10 command + int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command + BOOL FASTCALL TestUnitReady(const DWORD *cdb); // TEST UNIT READY command + int FASTCALL GetMessage10(const DWORD *cdb, BYTE *buf); // GET MESSAGE10 command + BOOL FASTCALL SendMessage10(const DWORD *cdb, BYTE *buf); // SEND MESSAGE10 command private: -#if defined(RASCSI) && !defined(BAREMETAL) - int FASTCALL GetMacAddr(BYTE *buf); - // Get MAC address - void FASTCALL SetMacAddr(BYTE *buf); - // Set MAC address - void FASTCALL ReceivePacket(); - // Receive a packet - void FASTCALL GetPacketBuf(BYTE *buf); - // Get a packet - void FASTCALL SendPacket(BYTE *buf, int len); - // Send a packet + #if defined(RASCSI) && !defined(BAREMETAL) + int FASTCALL GetMacAddr(BYTE *buf); // Get MAC address + void FASTCALL SetMacAddr(BYTE *buf); // Set MAC address + void FASTCALL ReceivePacket(); // Receive a packet + void FASTCALL GetPacketBuf(BYTE *buf); // Get a packet + void FASTCALL SendPacket(BYTE *buf, int len); // Send a packet - CTapDriver *tap; - // TAP driver - BOOL m_bTapEnable; - // TAP valid flag - BYTE mac_addr[6]; - // MAC Addres - int packet_len; - // Receive packet size - BYTE packet_buf[0x1000]; - // Receive packet buffer - BOOL packet_enable; - // Received packet valid -#endif // RASCSI && !BAREMETAL + CTapDriver *tap; // TAP driver + BOOL m_bTapEnable; // TAP valid flag + BYTE mac_addr[6]; // MAC Addres + int packet_len; // Receive packet size + BYTE packet_buf[0x1000]; // Receive packet buffer + BOOL packet_enable; // Received packet valid + #endif // RASCSI && !BAREMETAL + + int FASTCALL ReadFsResult(BYTE *buf); // Read filesystem (result code) + int FASTCALL ReadFsOut(BYTE *buf); // Read filesystem (return data) + int FASTCALL ReadFsOpt(BYTE *buf); // Read file system (optional data) + void FASTCALL WriteFs(int func, BYTE *buf); // File system write (execute) + void FASTCALL WriteFsOpt(BYTE *buf, int len); // File system write (optional data) - int FASTCALL ReadFsResult(BYTE *buf); - // Read filesystem (result code) - int FASTCALL ReadFsOut(BYTE *buf); - // Read filesystem (return data) - int FASTCALL ReadFsOpt(BYTE *buf); - // Read file system (optional data) - void FASTCALL WriteFs(int func, BYTE *buf); - // File system write (execute) - void FASTCALL WriteFsOpt(BYTE *buf, int len); - // File system write (optional data) // Command handlers - void FASTCALL FS_InitDevice(BYTE *buf); - // $40 - boot - void FASTCALL FS_CheckDir(BYTE *buf); - // $41 - directory check - void FASTCALL FS_MakeDir(BYTE *buf); - // $42 - create directory - void FASTCALL FS_RemoveDir(BYTE *buf); - // $43 - delete directory - void FASTCALL FS_Rename(BYTE *buf); - // $44 - change filename - void FASTCALL FS_Delete(BYTE *buf); - // $45 - delete file - void FASTCALL FS_Attribute(BYTE *buf); - // $46 - get/set file attributes - void FASTCALL FS_Files(BYTE *buf); - // $47 - file search - void FASTCALL FS_NFiles(BYTE *buf); - // $48 - find next file - void FASTCALL FS_Create(BYTE *buf); - // $49 - create file - void FASTCALL FS_Open(BYTE *buf); - // $4A - open file - void FASTCALL FS_Close(BYTE *buf); - // $4B - close file - void FASTCALL FS_Read(BYTE *buf); - // $4C - read file - void FASTCALL FS_Write(BYTE *buf); - // $4D - write file - void FASTCALL FS_Seek(BYTE *buf); - // $4E - seek file - void FASTCALL FS_TimeStamp(BYTE *buf); - // $4F - get/set file time - void FASTCALL FS_GetCapacity(BYTE *buf); - // $50 - get capacity - void FASTCALL FS_CtrlDrive(BYTE *buf); - // $51 - drive status check/control - void FASTCALL FS_GetDPB(BYTE *buf); - // $52 - get DPB - void FASTCALL FS_DiskRead(BYTE *buf); - // $53 - read sector - void FASTCALL FS_DiskWrite(BYTE *buf); - // $54 - write sector - void FASTCALL FS_Ioctrl(BYTE *buf); - // $55 - IOCTRL - void FASTCALL FS_Flush(BYTE *buf); - // $56 - flush cache - void FASTCALL FS_CheckMedia(BYTE *buf); - // $57 - check media - void FASTCALL FS_Lock(BYTE *buf); - // $58 - get exclusive control + void FASTCALL FS_InitDevice(BYTE *buf); // $40 - boot + void FASTCALL FS_CheckDir(BYTE *buf); // $41 - directory check + void FASTCALL FS_MakeDir(BYTE *buf); // $42 - create directory + void FASTCALL FS_RemoveDir(BYTE *buf); // $43 - delete directory + void FASTCALL FS_Rename(BYTE *buf); // $44 - change filename + void FASTCALL FS_Delete(BYTE *buf); // $45 - delete file + void FASTCALL FS_Attribute(BYTE *buf); // $46 - get/set file attributes + void FASTCALL FS_Files(BYTE *buf); // $47 - file search + void FASTCALL FS_NFiles(BYTE *buf); // $48 - find next file + void FASTCALL FS_Create(BYTE *buf); // $49 - create file + void FASTCALL FS_Open(BYTE *buf); // $4A - open file + void FASTCALL FS_Close(BYTE *buf); // $4B - close file + void FASTCALL FS_Read(BYTE *buf); // $4C - read file + void FASTCALL FS_Write(BYTE *buf); // $4D - write file + void FASTCALL FS_Seek(BYTE *buf); // $4E - seek file + void FASTCALL FS_TimeStamp(BYTE *buf); // $4F - get/set file time + void FASTCALL FS_GetCapacity(BYTE *buf); // $50 - get capacity + void FASTCALL FS_CtrlDrive(BYTE *buf); // $51 - drive status check/control + void FASTCALL FS_GetDPB(BYTE *buf); // $52 - get DPB + void FASTCALL FS_DiskRead(BYTE *buf); // $53 - read sector + void FASTCALL FS_DiskWrite(BYTE *buf); // $54 - write sector + void FASTCALL FS_Ioctrl(BYTE *buf); // $55 - IOCTRL + void FASTCALL FS_Flush(BYTE *buf); // $56 - flush cache + void FASTCALL FS_CheckMedia(BYTE *buf); // $57 - check media + void FASTCALL FS_Lock(BYTE *buf); // $58 - get exclusive control - CFileSys *fs; - // File system accessor - DWORD fsresult; - // File system access result code - BYTE fsout[0x800]; - // File system access result buffer - DWORD fsoutlen; - // File system access result buffer size - BYTE fsopt[0x1000000]; - // File system access buffer - DWORD fsoptlen; - // File system access buffer size + CFileSys *fs; // File system accessor + DWORD fsresult; // File system access result code + BYTE fsout[0x800]; // File system access result buffer + DWORD fsoutlen; // File system access result buffer size + BYTE fsopt[0x1000000]; // File system access buffer + DWORD fsoptlen; // File system access buffer size }; diff --git a/src/raspberrypi/devices/scsicd.cpp b/src/raspberrypi/devices/scsicd.cpp index d898f04c..8e91c1c4 100644 --- a/src/raspberrypi/devices/scsicd.cpp +++ b/src/raspberrypi/devices/scsicd.cpp @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI Hard Disk for Apple Macintosh ] +// [ SCSI Hard Disk for Apple Macintosh ] // //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/devices/scsicd.h b/src/raspberrypi/devices/scsicd.h index ca4b9070..ab703aab 100644 --- a/src/raspberrypi/devices/scsicd.h +++ b/src/raspberrypi/devices/scsicd.h @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI Hard Disk for Apple Macintosh ] +// [ SCSI Hard Disk for Apple Macintosh ] // //--------------------------------------------------------------------------- #pragma once @@ -36,50 +36,30 @@ class CDTrack { public: // Basic Functions - CDTrack(SCSICD *scsicd); - // Constructor - virtual ~CDTrack(); - // Destructor - BOOL FASTCALL Init(int track, DWORD first, DWORD last); - // Initialization + CDTrack(SCSICD *scsicd); // Constructor + virtual ~CDTrack(); // Destructor + BOOL FASTCALL Init(int track, DWORD first, DWORD last); // Initialization // Properties - void FASTCALL SetPath(BOOL cdda, const Filepath& path); - // Set the path - void FASTCALL GetPath(Filepath& path) const; - // Get the path - void FASTCALL AddIndex(int index, DWORD lba); - // Add index - DWORD FASTCALL GetFirst() const; - // Get the start LBA - DWORD FASTCALL GetLast() const; - // Get the last LBA - DWORD FASTCALL GetBlocks() const; - // Get the number of blocks - int FASTCALL GetTrackNo() const; - // Get the track number - BOOL FASTCALL IsValid(DWORD lba) const; - // Is this a valid LBA? - BOOL FASTCALL IsAudio() const; - // Is this an audio track? + void FASTCALL SetPath(BOOL cdda, const Filepath& path); // Set the path + void FASTCALL GetPath(Filepath& path) const; // Get the path + void FASTCALL AddIndex(int index, DWORD lba); // Add index + DWORD FASTCALL GetFirst() const; // Get the start LBA + DWORD FASTCALL GetLast() const; // Get the last LBA + DWORD FASTCALL GetBlocks() const; // Get the number of blocks + int FASTCALL GetTrackNo() const; // Get the track number + BOOL FASTCALL IsValid(DWORD lba) const; // Is this a valid LBA? + BOOL FASTCALL IsAudio() const; // Is this an audio track? private: - SCSICD *cdrom; - // Parent device - BOOL valid; - // Valid track - int track_no; - // Track number - DWORD first_lba; - // First LBA - DWORD last_lba; - // Last LBA - BOOL audio; - // Audio track flag - BOOL raw; - // RAW data flag - Filepath imgpath; - // Image file path + SCSICD *cdrom; // Parent device + BOOL valid; // Valid track + int track_no; // Track number + DWORD first_lba; // First LBA + DWORD last_lba; // Last LBA + BOOL audio; // Audio track flag + BOOL raw; // RAW data flag + Filepath imgpath; // Image file path }; //=========================================================================== @@ -91,47 +71,29 @@ class CDDABuf { public: // Basic Functions - CDDABuf(); - // Constructor - virtual ~CDDABuf(); - // Destructor -#if 0 - BOOL Init(); - // Initialization - BOOL FASTCALL Load(const Filepath& path); - // Load - BOOL FASTCALL Save(const Filepath& path); - // Save + CDDABuf(); // Constructor + virtual ~CDDABuf(); // Destructor + #if 0 + BOOL Init(); // Initialization + BOOL FASTCALL Load(const Filepath& path); // Load + BOOL FASTCALL Save(const Filepath& path); // Save // API - void FASTCALL Clear(); - // Clear the buffer - BOOL FASTCALL Open(Filepath& path); - // File specification - BOOL FASTCALL GetBuf(DWORD *buffer, int frames); - // Get the buffer - BOOL FASTCALL IsValid(); - // Check if Valid - BOOL FASTCALL ReadReq(); - // Read Request - BOOL FASTCALL IsEnd() const; - // Finish check + void FASTCALL Clear(); // Clear the buffer + BOOL FASTCALL Open(Filepath& path); // File specification + BOOL FASTCALL GetBuf(DWORD *buffer, int frames); // Get the buffer + BOOL FASTCALL IsValid(); // Check if Valid + BOOL FASTCALL ReadReq(); // Read Request + BOOL FASTCALL IsEnd() const; // Finish check private: - Filepath wavepath; - // Wave path - BOOL valid; - // Open result (is it valid?) - DWORD *buf; - // Data buffer - DWORD read; - // Read pointer - DWORD write; - // Write pointer - DWORD num; - // Valid number of data - DWORD rest; - // Remaining file size + Filepath wavepath; // Wave path + BOOL valid; // Open result (is it valid?) + DWORD *buf; // Data buffer + DWORD read; // Read pointer + DWORD write; // Write pointer + DWORD num; // Valid number of data + DWORD rest; // Remaining file size #endif }; @@ -145,86 +107,56 @@ class SCSICD : public Disk public: // Number of tracks enum { - TrackMax = 96 // Maximum number of tracks + TrackMax = 96 // Maximum number of tracks }; public: // Basic Functions - SCSICD(); - // Constructor - virtual ~SCSICD(); - // Destructor - BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); - // Open -#ifndef RASCSI - BOOL FASTCALL Load(Fileio *fio, int ver); - // Load -#endif // RASCSI + SCSICD(); // Constructor + virtual ~SCSICD(); // Destructor + BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); // Open + #ifndef RASCSI + BOOL FASTCALL Load(Fileio *fio, int ver); // Load + #endif // RASCSI // commands - int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); - // INQUIRY command - int FASTCALL Read(BYTE *buf, DWORD block); - // READ command - int FASTCALL ReadToc(const DWORD *cdb, BYTE *buf); - // READ TOC command - BOOL FASTCALL PlayAudio(const DWORD *cdb); - // PLAY AUDIO command - BOOL FASTCALL PlayAudioMSF(const DWORD *cdb); - // PLAY AUDIO MSF command - BOOL FASTCALL PlayAudioTrack(const DWORD *cdb); - // PLAY AUDIO TRACK command + int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command + int FASTCALL Read(BYTE *buf, DWORD block); // READ command + int FASTCALL ReadToc(const DWORD *cdb, BYTE *buf); // READ TOC command + BOOL FASTCALL PlayAudio(const DWORD *cdb); // PLAY AUDIO command + BOOL FASTCALL PlayAudioMSF(const DWORD *cdb); // PLAY AUDIO MSF command + BOOL FASTCALL PlayAudioTrack(const DWORD *cdb); // PLAY AUDIO TRACK command // CD-DA - BOOL FASTCALL NextFrame(); - // Frame notification - void FASTCALL GetBuf(DWORD *buffer, int samples, DWORD rate); - // Get CD-DA buffer + BOOL FASTCALL NextFrame(); // Frame notification + void FASTCALL GetBuf(DWORD *buffer, int samples, DWORD rate); // Get CD-DA buffer // LBA-MSF変換 - void FASTCALL LBAtoMSF(DWORD lba, BYTE *msf) const; - // LBA→MSF conversion - DWORD FASTCALL MSFtoLBA(const BYTE *msf) const; - // MSF→LBA conversion + void FASTCALL LBAtoMSF(DWORD lba, BYTE *msf) const; // LBA→MSF conversion + DWORD FASTCALL MSFtoLBA(const BYTE *msf) const; // MSF→LBA conversion private: // Open - BOOL FASTCALL OpenCue(const Filepath& path); - // Open(CUE) - BOOL FASTCALL OpenIso(const Filepath& path); - // Open(ISO) - BOOL FASTCALL OpenPhysical(const Filepath& path); - // Open(Physical) - BOOL rawfile; - // RAW flag + BOOL FASTCALL OpenCue(const Filepath& path); // Open(CUE) + BOOL FASTCALL OpenIso(const Filepath& path); // Open(ISO) + BOOL FASTCALL OpenPhysical(const Filepath& path); // Open(Physical) + BOOL rawfile; // RAW flag // Track management - void FASTCALL ClearTrack(); - // Clear the track - int FASTCALL SearchTrack(DWORD lba) const; - // Track search - CDTrack* track[TrackMax]; - // Track opbject references - int tracks; - // Effective number of track objects - int dataindex; - // Current data track - int audioindex; - // Current audio track + void FASTCALL ClearTrack(); // Clear the track + int FASTCALL SearchTrack(DWORD lba) const; // Track search + CDTrack* track[TrackMax]; // Track opbject references + int tracks; // Effective number of track objects + int dataindex; // Current data track + int audioindex; // Current audio track - int frame; - // Frame number + int frame; // Frame number -#if 0 - CDDABuf da_buf; - // CD-DA buffer - int da_num; - // Number of CD-DA tracks - int da_cur; - // CD-DA current track - int da_next; - // CD-DA next track - BOOL da_req; - // CD-DA data request -#endif + #if 0 + CDDABuf da_buf; // CD-DA buffer + int da_num; // Number of CD-DA tracks + int da_cur; // CD-DA current track + int da_next; // CD-DA next track + BOOL da_req; // CD-DA data request + #endif }; diff --git a/src/raspberrypi/devices/scsihd.cpp b/src/raspberrypi/devices/scsihd.cpp index ed4c32b1..67e8bf68 100644 --- a/src/raspberrypi/devices/scsihd.cpp +++ b/src/raspberrypi/devices/scsihd.cpp @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI hard disk ] +// [ SCSI hard disk ] // //--------------------------------------------------------------------------- #include "scsihd.h" diff --git a/src/raspberrypi/devices/scsihd.h b/src/raspberrypi/devices/scsihd.h index 2f08bdfe..95f5a009 100644 --- a/src/raspberrypi/devices/scsihd.h +++ b/src/raspberrypi/devices/scsihd.h @@ -5,10 +5,10 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // // [ SCSI hard disk ] // @@ -28,17 +28,11 @@ class SCSIHD : public Disk { public: // Basic Functions - SCSIHD(); - // Constructor - void FASTCALL Reset(); - // Reset - BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); - // Open + SCSIHD(); // Constructor + void FASTCALL Reset(); // Reset + BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); // Open // commands - int FASTCALL Inquiry( - const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); - // INQUIRY command - BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length); - // MODE SELECT(6) command + int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command + BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length); // MODE SELECT(6) command }; \ No newline at end of file diff --git a/src/raspberrypi/devices/scsihd_apple.cpp b/src/raspberrypi/devices/scsihd_apple.cpp index c244d3ea..9636a987 100644 --- a/src/raspberrypi/devices/scsihd_apple.cpp +++ b/src/raspberrypi/devices/scsihd_apple.cpp @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI Hard Disk for Apple Macintosh ] +// [ SCSI Hard Disk for Apple Macintosh ] // //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/devices/scsihd_apple.h b/src/raspberrypi/devices/scsihd_apple.h index a78d16c1..12db7613 100644 --- a/src/raspberrypi/devices/scsihd_apple.h +++ b/src/raspberrypi/devices/scsihd_apple.h @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI Hard Disk for Apple Macintosh ] +// [ SCSI Hard Disk for Apple Macintosh ] // //--------------------------------------------------------------------------- #pragma once @@ -26,14 +26,10 @@ class SCSIHD_APPLE : public SCSIHD { public: // Basic Functions - SCSIHD_APPLE(); - // Constructor + SCSIHD_APPLE(); // Constructor // commands - int FASTCALL Inquiry( - const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); - // INQUIRY command + int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command // Internal processing - int FASTCALL AddVendor(int page, BOOL change, BYTE *buf); - // Add vendor special page + int FASTCALL AddVendor(int page, BOOL change, BYTE *buf); // Add vendor special page }; \ No newline at end of file diff --git a/src/raspberrypi/devices/scsihd_nec.cpp b/src/raspberrypi/devices/scsihd_nec.cpp index d8a0a7e4..856e646e 100644 --- a/src/raspberrypi/devices/scsihd_nec.cpp +++ b/src/raspberrypi/devices/scsihd_nec.cpp @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI NEC "Genuine" Hard Disk] +// [ SCSI NEC "Genuine" Hard Disk] // //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/devices/scsihd_nec.h b/src/raspberrypi/devices/scsihd_nec.h index 270bf6bc..01518957 100644 --- a/src/raspberrypi/devices/scsihd_nec.h +++ b/src/raspberrypi/devices/scsihd_nec.h @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI NEC "Genuine" Hard Disk] +// [ SCSI NEC "Genuine" Hard Disk] // //--------------------------------------------------------------------------- #pragma once @@ -26,36 +26,22 @@ class SCSIHD_NEC : public SCSIHD { public: // Basic Functions - SCSIHD_NEC(); - // Constructor - - BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); - // Open + SCSIHD_NEC(); // Constructor + BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); // Open // commands - int FASTCALL Inquiry( - const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); - // INQUIRY command + int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command // Internal processing - int FASTCALL AddError(BOOL change, BYTE *buf); - // Add error - int FASTCALL AddFormat(BOOL change, BYTE *buf); - // Add format - int FASTCALL AddDrive(BOOL change, BYTE *buf); - // Add drive + int FASTCALL AddError(BOOL change, BYTE *buf); // Add error + int FASTCALL AddFormat(BOOL change, BYTE *buf); // Add format + int FASTCALL AddDrive(BOOL change, BYTE *buf); // Add drive private: - int cylinders; - // Number of cylinders - int heads; - // Number of heads - int sectors; - // Number of sectors - int sectorsize; - // Sector size - off64_t imgoffset; - // Image offset - off64_t imgsize; - // Image size + int cylinders; // Number of cylinders + int heads; // Number of heads + int sectors; // Number of sectors + int sectorsize; // Sector size + off64_t imgoffset; // Image offset + off64_t imgsize; // Image size }; \ No newline at end of file diff --git a/src/raspberrypi/devices/scsimo.cpp b/src/raspberrypi/devices/scsimo.cpp index 64d363cc..c6849d65 100644 --- a/src/raspberrypi/devices/scsimo.cpp +++ b/src/raspberrypi/devices/scsimo.cpp @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI Magneto-Optical Disk] +// [ SCSI Magneto-Optical Disk] // //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/devices/scsimo.h b/src/raspberrypi/devices/scsimo.h index f8aa2990..fdf8629a 100644 --- a/src/raspberrypi/devices/scsimo.h +++ b/src/raspberrypi/devices/scsimo.h @@ -5,12 +5,12 @@ // // Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) // Copyright (C) 2014-2020 GIMONS -// Copyright (C) akuker +// Copyright (C) akuker // -// Licensed under the BSD 3-Clause License. -// See LICENSE file in the project root folder. +// Licensed under the BSD 3-Clause License. +// See LICENSE file in the project root folder. // -// [ SCSI Magneto-Optical Disk] +// [ SCSI Magneto-Optical Disk] // //--------------------------------------------------------------------------- #pragma once @@ -28,22 +28,16 @@ class SCSIMO : public Disk { public: // Basic Functions - SCSIMO(); - // Constructor - BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); - // Open -#ifndef RASCSI - BOOL FASTCALL Load(Fileio *fio, int ver); - // Load -#endif // RASCSI + SCSIMO(); // Constructor + BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); // Open + #ifndef RASCSI + BOOL FASTCALL Load(Fileio *fio, int ver); // Load + #endif // RASCSI // commands - int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); - // INQUIRY command - BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length); - // MODE SELECT(6) command + int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command + BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length); // MODE SELECT(6) command // Internal processing - int FASTCALL AddVendor(int page, BOOL change, BYTE *buf); - // Add vendor special page + int FASTCALL AddVendor(int page, BOOL change, BYTE *buf); // Add vendor special page }; \ No newline at end of file From aec10b45efe134af77866e017225da66d4ec78fa Mon Sep 17 00:00:00 2001 From: akuker Date: Mon, 5 Apr 2021 16:38:39 -0500 Subject: [PATCH 22/22] Cleanup test procedure to allow service to be inactive OR failed --- test/robot/Resources/linux_services.resource | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/robot/Resources/linux_services.resource b/test/robot/Resources/linux_services.resource index 5389cd8b..e518e2f4 100644 --- a/test/robot/Resources/linux_services.resource +++ b/test/robot/Resources/linux_services.resource @@ -15,7 +15,7 @@ The ${service_name} Service Should be Running The ${service_name} Service Should be Stopped ${lc_service_name}= Convert To Lower Case ${service_name} ${output}= Execute Command systemctl status ${lc_service_name} - Should Contain ${output} Active: failed ignore_case=True + Should Contain Any ${output} Active: failed Active: inactive ignore_case=True The ${service_name} Service is Stopped ${lc_service_name}= Convert To Lower Case ${service_name}