From 19cc9ad169880d34f98bbdc79e1b7213557c8bd3 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Sat, 21 May 2022 13:18:37 -0500 Subject: [PATCH 1/7] Implement 3 commands: SCSI Read Buffer (Thanks @marcelv-3!) SCSI Write Buffer (Thanks @marcelv-3!) ReZero Unit --- src/BlueSCSI.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++++++- src/scsi_mode.h | 9 +++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/scsi_mode.h diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index e9a3074..85b778e 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -41,6 +41,7 @@ #include "scsi_cmds.h" #include "scsi_sense.h" #include "scsi_status.h" +#include "scsi_mode.h" #ifdef USE_STM32_DMA #warning "warning USE_STM32_DMA" @@ -245,6 +246,7 @@ byte m_sts; // Status byte byte m_msg; // Message bytes HDDIMG *m_img; // HDD image for current SCSI-ID, LUN byte m_buf[MAX_BLOCKSIZE]; // General purpose buffer +byte m_scsi_buf[512]; // Buffer for SCSI READ/WRITE Buffer byte m_msb[256]; // Command storage bytes /* @@ -1334,10 +1336,12 @@ byte onModeSelectCommand(byte scsi_cmd, byte flags, uint32_t len) //0 0 0 8 0 0 0 0 0 0 2 0 0 2 10 0 1 6 24 10 8 0 0 0 //I believe mode page 0 set to 10 00 is Disable Unit Attention //Mode page 1 set to 24 10 08 00 00 00 is TB and PER set, read retry count 16, correction span 8 + #if DEBUG > 0 for (unsigned i = 0; i < len; i++) { LOGHEX(m_buf[i]);LOG(" "); } LOGN(""); + #endif return SCSI_STATUS_GOOD; } @@ -1354,6 +1358,90 @@ byte onTestUnitReady() } return SCSI_STATUS_GOOD; } +/* + * ReZero Unit - Move to Logical Block Zero in file. + */ +byte onReZeroUnit() { + LOGN("-ReZeroUnit"); + // Make sure we have an image with atleast a first byte. + // Actually seeking to the position wont do anything, so dont. + return checkBlockCommand(0, 0); +} + +/* + * WriteBuffer - Used for testing buffer, no change to medium + */ +byte onWriteBuffer(byte mode, uint32_t allocLength) +{ + LOGN("-WriteBuffer"); + LOGHEXN(mode); + LOGHEXN(allocLength); + + if ((mode == MODE_COMBINED_HEADER_DATA || mode == MODE_DATA) && allocLength <= sizeof(m_scsi_buf)) + { + readDataPhase(allocLength, m_scsi_buf); + #if DEBUG > 0 + for (unsigned i = 0; i < allocLength; i++) { + LOGHEX(m_buf[i]);LOG(" "); + } + LOGN(""); + #endif + return SCSI_STATUS_GOOD; + } + else + { + m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST; + m_addition_sense = SCSI_ASC_INVALID_FIELD_IN_CDB; + return SCSI_STATUS_CHECK_CONDITION; + } +} + +/* + * ReadBuffer - Used for testing buffer, no change to medium + */ +byte onReadBuffer(byte mode, uint32_t allocLength) +{ + LOGN("-ReadBuffer"); + LOGHEXN(mode); + LOGHEXN(allocLength); + + if (mode == MODE_COMBINED_HEADER_DATA) + { + uint32_t bufCapacity = sizeof(m_scsi_buf) - 4; + // four byte read buffer header + m_scsi_buf[0] = 0; + m_scsi_buf[1] = (bufCapacity >> 16) & 0xff; + m_scsi_buf[2] = (bufCapacity >> 8) & 0xff; + m_scsi_buf[3] = bufCapacity & 0xff; + + writeDataPhase(allocLength, m_scsi_buf); + + #if DEBUG > 0 + for (unsigned i = 0; i < allocLength; i++) { + LOGHEX(m_scsi_buf[i]);LOG(" "); + } + LOGN(""); + #endif + return SCSI_STATUS_GOOD; + } + else if (mode == MODE_DATA) + { + writeDataPhase(allocLength, m_scsi_buf); + #if DEBUG > 0 + for (unsigned i = 0; i < allocLength; i++) { + LOGHEX(m_scsi_buf[i]);LOG(" "); + } + LOGN(""); + #endif + return SCSI_STATUS_GOOD; + } + else + { + m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST; + m_addition_sense = SCSI_ASC_INVALID_FIELD_IN_CDB; + return SCSI_STATUS_CHECK_CONDITION; + } +} /* * MsgIn2. @@ -1521,8 +1609,9 @@ void loop() LOGN("[Test Unit Ready]"); m_sts |= onTestUnitReady(); break; - case SCSI_REZERO_UNIT: // TODO: Implement me! + case SCSI_REZERO_UNIT: LOGN("[Rezero Unit]"); + m_sts |= onReZeroUnit(); break; case SCSI_REQUEST_SENSE: LOGN("[RequestSense]"); @@ -1596,6 +1685,14 @@ void loop() LOGN("[ModeSense10]"); m_sts |= onModeSenseCommand(cmd[0], cmd[1] & 0x80, cmd[2], ((uint32_t)cmd[7] << 8) | cmd[8]); break; + case SCSI_WRITE_BUFFER: + LOGN("[WriteBuffer]"); + m_sts |= onWriteBuffer(cmd[1] & 7, ((uint32_t)cmd[6] << 16) | ((uint32_t)cmd[7] << 8) | cmd[8]); + break; + case SCSI_READ_BUFFER: + LOGN("[ReadBuffer]"); + m_sts |= onReadBuffer(cmd[1] & 7, ((uint32_t)cmd[6] << 16) | ((uint32_t)cmd[7] << 8) | cmd[8]); + break; default: LOGN("[*Unknown]"); m_sts |= SCSI_STATUS_CHECK_CONDITION; diff --git a/src/scsi_mode.h b/src/scsi_mode.h new file mode 100644 index 0000000..fe9d8e4 --- /dev/null +++ b/src/scsi_mode.h @@ -0,0 +1,9 @@ +#ifndef __SCSI_MODE_H__ +#define __SCSI_MODE_H__ + +#define MODE_COMBINED_HEADER_DATA 0x00 +#define MODE_NOT_SUPPORTED 0x01 +#define MODE_DATA 0x02 +#define MODE_DESCRIPTOR 0x03 + +#endif \ No newline at end of file From 61ae8a59dbffdae9b0fde37bd47b3a9c2c24e067 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Sat, 21 May 2022 15:51:07 -0500 Subject: [PATCH 2/7] Add constants for SCSI mode page codes --- src/BlueSCSI.cpp | 36 ++++++++++++++++++------------------ src/scsi_sense.h | 13 +++++++++++++ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index 85b778e..9b919fa 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -1241,7 +1241,7 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len) int pageCode = cmd2 & 0x3F; int pageControl = cmd2 >> 6; int a = 4; - if(scsi_cmd == 0x5A) a = 8; + if(scsi_cmd == SCSI_MODE_SENSE10) a = 8; if(dbd == 0) { byte c[8] = { @@ -1254,21 +1254,21 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len) a += 8; } switch(pageCode) { - case 0x3F: - case 0x01: // Read/Write Error Recovery - m_buf[a + 0] = 0x01; + case SCSI_SENSE_MODE_ALL: + case SCSI_SENSE_MODE_READ_WRITE_ERROR_RECOVERY: + m_buf[a + 0] = SCSI_SENSE_MODE_READ_WRITE_ERROR_RECOVERY; m_buf[a + 1] = 0x0A; a += 0x0C; - if(pageCode != 0x3F) break; + if(pageCode != SCSI_SENSE_MODE_ALL) break; - case 0x02: // Disconnect-Reconnect page - m_buf[a + 0] = 0x02; + case SCSI_SENSE_MODE_DISCONNECT_RECONNECT: + m_buf[a + 0] = SCSI_SENSE_MODE_DISCONNECT_RECONNECT; m_buf[a + 1] = 0x0A; a += 0x0C; - if(pageCode != 0x3f) break; + if(pageCode != SCSI_SENSE_MODE_ALL) break; - case 0x03: //Drive parameters - m_buf[a + 0] = 0x03; //Page code + case SCSI_SENSE_MODE_FORMAT_DEVICE: //Drive parameters + m_buf[a + 0] = SCSI_SENSE_MODE_FORMAT_DEVICE; //Page code m_buf[a + 1] = 0x16; // Page length if(pageControl != 1) { m_buf[a + 11] = 0x3F;//Number of sectors / track @@ -1277,10 +1277,10 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len) m_buf[a + 15] = 0x1; // Interleave } a += 0x18; - if(pageCode != 0x3F) break; + if(pageCode != SCSI_SENSE_MODE_ALL) break; - case 0x04: //Drive parameters - m_buf[a + 0] = 0x04; //Page code + case SCSI_SENSE_MODE_DISK_GEOMETRY: //Drive parameters + m_buf[a + 0] = SCSI_SENSE_MODE_DISK_GEOMETRY; //Page code m_buf[a + 1] = 0x16; // Page length if(pageControl != 1) { unsigned cylinders = bc / (16 * 63); @@ -1290,19 +1290,19 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len) m_buf[a + 5] = 16; //Number of heads } a += 0x18; - if(pageCode != 0x3F) break; - case 0x30: + if(pageCode != SCSI_SENSE_MODE_ALL) break; + case SCSI_SENSE_MODE_VENDOR_APPLE: { const byte page30[0x14] = {0x41, 0x50, 0x50, 0x4C, 0x45, 0x20, 0x43, 0x4F, 0x4D, 0x50, 0x55, 0x54, 0x45, 0x52, 0x2C, 0x20, 0x49, 0x4E, 0x43, 0x20}; - m_buf[a + 0] = 0x30; // Page code + m_buf[a + 0] = SCSI_SENSE_MODE_VENDOR_APPLE; // Page code m_buf[a + 1] = sizeof(page30); // Page length if(pageControl != 1) { memcpy(&m_buf[a + 2], page30, sizeof(page30)); } a += 2 + sizeof(page30); - if(pageCode != 0x3F) break; + if(pageCode != SCSI_SENSE_MODE_ALL) break; } - break; // Don't want 0x3F falling through to error condition + break; // Don't want SCSI_SENSE_MODE_ALL falling through to error condition default: m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST; diff --git a/src/scsi_sense.h b/src/scsi_sense.h index 15895a8..5a10218 100644 --- a/src/scsi_sense.h +++ b/src/scsi_sense.h @@ -29,4 +29,17 @@ #define SCSI_ASC_CANNOT_READ_MEDIUM_INCOMPATIBLE_FORMAT 0x3002 #define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A00 #define SCSI_ASC_LUN_NOT_READY_MANUAL_INTERVENTION_REQUIRED 0x0403 + + +// SCSI mode page codes +#define SCSI_SENSE_MODE_VENDOR 0x00 +#define SCSI_SENSE_MODE_READ_WRITE_ERROR_RECOVERY 0x01 +#define SCSI_SENSE_MODE_DISCONNECT_RECONNECT 0x02 +#define SCSI_SENSE_MODE_FORMAT_DEVICE 0x03 +#define SCSI_SENSE_MODE_DISK_GEOMETRY 0x04 +#define SCSI_SENSE_MODE_VENDOR_APPLE 0x30 + +#define SCSI_SENSE_MODE_ALL 0x3F + + #endif \ No newline at end of file From 5c0724703b9eddbf6acb7720df1321f44db3a0da Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Sun, 22 May 2022 12:53:57 -0500 Subject: [PATCH 3/7] Fix build for USB --- platformio.ini | 69 +++++++++++++++++++++++++++++------------------- src/BlueSCSI.cpp | 4 +-- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/platformio.ini b/platformio.ini index 289b9d4..a04c86e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -32,50 +32,65 @@ board_build.core = maple [env:STM32F1-XCVR] extends = env:STM32F1 -build_flags = ${env.build_flags} +build_flags = ${env.build_flags} -DXCVR -D BUILD_TAGS="\"-XCVR\"" -[env:STM32F1-USB] -extends = env:STM32F1 -build_flags = ${env.build_flags} - -D BUILD_TAGS="\"-USB\"" +[env:STM32F1-USB-128MHz] +# Max overclock for STM32 +# Can use for APM32F1 as well. +extends = env:STM32F1-USB +board_build.f_cpu = 128000000L +build_flags = ${env.build_flags} + -D BUILD_TAGS="\"-USB-128MHz\"" + +[env:STM32F1-USB-96MHz] +# Slight overclock for STM32 +# Use for APM32F1's - it's default clock is 96MHz and runs unstable at 72MHz(STM32F1's default) +extends = env:STM32F1-USB +# Explicilty define the multiplier as maple only handles a few cases. +build_flags = ${env.build_flags} + -D BUILD_TAGS="\"-USB-96MHz\"" -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC -D USBCON -D USBD_VID=0x0483 -D USB_MANUFACTURER="Unknown" -D USB_PRODUCT="\"BLUEPILL_F103C8\"" -D HAL_PCD_MODULE_ENABLED - -[env:STM32F1-USB-128MHZ] -extends = env:STM32F1 -board_build.f_cpu = 128000000L -build_flags = ${env.build_flags} - -D BUILD_TAGS="\"-USB-128MHZ\"" - -[env:APM32F1] -# The APM32F1's default clock is 96MHz and runs unstable at 72MHz(STM32F1's default) -extends = env:STM32F1 -# Explicilty define the multiplier as maple only handles a few cases. -build_flags = ${env.build_flags} - -D BUILD_TAGS="\"-APM32\"" -DBOARD_RCC_PLLMUL=RCC_PLLMUL_12 #96000000L -[env:APM32F1-USB] -# The APM32F1's default clock is 96MHz and runs unstable at 72MHz(STM32F1's default) -extends = env:APM32F1 -# Explicilty define the multiplier as maple only handles a few cases. -build_flags = ${env.build_flags} - -D BUILD_TAGS="\"-APM32-USB\"" +# TODO: Find out why USB build flags get trampled when extending an extended env. +[env:STM32F1-USB] +platform = ststm32 +board = genericSTM32F103C8 +board_build.mcu = stm32f103c8t6 +board_build.core = maple +board_build.f_cpu = 128000000L +framework = arduino +lib_deps = + greiman/SdFat @ ^2.0.6 +upload_protocol = dfu +; Different gcc versions produce much different binaries in terms of speed. +platform_packages = platformio/toolchain-gccarmnoneeabi@1.90301.200702 +build_flags = + -D BUILD_TAGS="\"-USB\"" -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC -D USBCON -D USBD_VID=0x0483 -D USB_MANUFACTURER="Unknown" -D USB_PRODUCT="\"BLUEPILL_F103C8\"" -D HAL_PCD_MODULE_ENABLED - -DBOARD_RCC_PLLMUL=RCC_PLLMUL_12 #96000000L -# Or go all out at 128Mhz, your call :) -#board_build.f_cpu = 128000000L + -w + -DARDUINO_GENERIC_STM32F103C + -DARDUINO_LIB_DISCOVERY_PHASE + -DARDUINO=10813 + -DARDUINO_ARCH_STM32 + -DDEBUG_LEVEL=DEBUG_NONE + -O2 +build_unflags = + -Os + -DARDUINO_ARCH_STM32F1 +upload_flags = -c set CPUTAPID 0 ; [env:debug] ; build_type = debug diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index 9b919fa..c229701 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -278,7 +278,7 @@ uint32_t db_bsrr[256]; //#undef PTY // Log File -#define VERSION "1.1-SNAPSHOT-20220407" +#define VERSION "1.1-SNAPSHOT-20220522" #define LOG_FILENAME "LOG.txt" FsFile LOG_FILE; @@ -681,7 +681,7 @@ void initFileLog(int success_mhz) { LOG_FILE.println(SDFAT_FILE_TYPE); LOG_FILE.print("SdFat version: "); LOG_FILE.println(SD_FAT_VERSION_STR); - LOG_FILE.print("SD Format: "); + LOG_FILE.print("Sd Format: "); switch(SD.vol()->fatType()) { case FAT_TYPE_EXFAT: LOG_FILE.println("exFAT"); From 20cb5d8552d8d43763ca6fdfa0007f2acefe93c8 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Mon, 23 May 2022 17:13:09 -0500 Subject: [PATCH 4/7] Prepend the header to the buffer data --- src/BlueSCSI.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index c229701..d7d81ad 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -1407,14 +1407,17 @@ byte onReadBuffer(byte mode, uint32_t allocLength) if (mode == MODE_COMBINED_HEADER_DATA) { - uint32_t bufCapacity = sizeof(m_scsi_buf) - 4; + uint32_t bufCapacity = sizeof(m_scsi_buf); + byte scsi_buf_response[bufCapacity + 4]; // four byte read buffer header - m_scsi_buf[0] = 0; - m_scsi_buf[1] = (bufCapacity >> 16) & 0xff; - m_scsi_buf[2] = (bufCapacity >> 8) & 0xff; - m_scsi_buf[3] = bufCapacity & 0xff; - - writeDataPhase(allocLength, m_scsi_buf); + scsi_buf_response[0] = 0; + scsi_buf_response[1] = (bufCapacity >> 16) & 0xff; + scsi_buf_response[2] = (bufCapacity >> 8) & 0xff; + scsi_buf_response[3] = bufCapacity & 0xff; + // actual data + memcpy((&scsi_buf_response[4]), m_scsi_buf, bufCapacity); + + writeDataPhase(sizeof(scsi_buf_response), scsi_buf_response); #if DEBUG > 0 for (unsigned i = 0; i < allocLength; i++) { From 7cdddf7371797da139796d4b1d43720feb672f42 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Tue, 24 May 2022 13:37:17 -0500 Subject: [PATCH 5/7] Fix header handling in scsi buffer --- src/BlueSCSI.cpp | 51 ++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index d7d81ad..d7f0b83 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -55,7 +55,7 @@ #define NUM_SCSIID 7 // Maximum number of supported SCSI-IDs (The minimum is 0) #define NUM_SCSILUN 2 // Maximum number of LUNs supported (The minimum is 0) #define READ_PARITY_CHECK 0 // Perform read parity check (unverified) - +#define SCSI_BUF_SIZE 512 // Size of the SCSI Buffer // HDD format #define MAX_BLOCKSIZE 2048 // Maximum BLOCK size @@ -239,15 +239,15 @@ volatile bool m_isBusReset = false; // Bus reset volatile bool m_resetJmp = false; // Call longjmp on reset jmp_buf m_resetJmpBuf; -byte scsi_id_mask; // Mask list of responding SCSI IDs -byte m_id; // Currently responding SCSI-ID -byte m_lun; // Logical unit number currently responding -byte m_sts; // Status byte -byte m_msg; // Message bytes -HDDIMG *m_img; // HDD image for current SCSI-ID, LUN -byte m_buf[MAX_BLOCKSIZE]; // General purpose buffer -byte m_scsi_buf[512]; // Buffer for SCSI READ/WRITE Buffer -byte m_msb[256]; // Command storage bytes +byte scsi_id_mask; // Mask list of responding SCSI IDs +byte m_id; // Currently responding SCSI-ID +byte m_lun; // Logical unit number currently responding +byte m_sts; // Status byte +byte m_msg; // Message bytes +HDDIMG *m_img; // HDD image for current SCSI-ID, LUN +byte m_buf[MAX_BLOCKSIZE]; // General purpose buffer +byte m_scsi_buf[SCSI_BUF_SIZE]; // Buffer for SCSI READ/WRITE Buffer +byte m_msb[256]; // Command storage bytes /* * Data byte to BSRR register setting value and parity table @@ -1377,12 +1377,26 @@ byte onWriteBuffer(byte mode, uint32_t allocLength) LOGHEXN(mode); LOGHEXN(allocLength); - if ((mode == MODE_COMBINED_HEADER_DATA || mode == MODE_DATA) && allocLength <= sizeof(m_scsi_buf)) + if (mode == MODE_COMBINED_HEADER_DATA && (allocLength - 4) <= SCSI_BUF_SIZE) + { + byte tmp[allocLength]; + readDataPhase(allocLength, tmp); + // Drop header + memcpy(m_scsi_buf, (&tmp[4]), allocLength - 4); + #if DEBUG > 0 + for (unsigned i = 0; i < allocLength; i++) { + LOGHEX(tmp[i]);LOG(" "); + } + LOGN(""); + #endif + return SCSI_STATUS_GOOD; + } + else if ( mode == MODE_DATA && allocLength <= SCSI_BUF_SIZE) { readDataPhase(allocLength, m_scsi_buf); #if DEBUG > 0 for (unsigned i = 0; i < allocLength; i++) { - LOGHEX(m_buf[i]);LOG(" "); + LOGHEX(m_scsi_buf[i]);LOG(" "); } LOGN(""); #endif @@ -1407,17 +1421,16 @@ byte onReadBuffer(byte mode, uint32_t allocLength) if (mode == MODE_COMBINED_HEADER_DATA) { - uint32_t bufCapacity = sizeof(m_scsi_buf); - byte scsi_buf_response[bufCapacity + 4]; + byte scsi_buf_response[SCSI_BUF_SIZE + 4]; // four byte read buffer header scsi_buf_response[0] = 0; - scsi_buf_response[1] = (bufCapacity >> 16) & 0xff; - scsi_buf_response[2] = (bufCapacity >> 8) & 0xff; - scsi_buf_response[3] = bufCapacity & 0xff; + scsi_buf_response[1] = (SCSI_BUF_SIZE >> 16) & 0xff; + scsi_buf_response[2] = (SCSI_BUF_SIZE >> 8) & 0xff; + scsi_buf_response[3] = SCSI_BUF_SIZE & 0xff; // actual data - memcpy((&scsi_buf_response[4]), m_scsi_buf, bufCapacity); + memcpy((&scsi_buf_response[4]), m_scsi_buf, SCSI_BUF_SIZE); - writeDataPhase(sizeof(scsi_buf_response), scsi_buf_response); + writeDataPhase(SCSI_BUF_SIZE + 4, scsi_buf_response); #if DEBUG > 0 for (unsigned i = 0; i < allocLength; i++) { From 3c258451fa342c5ec6fee98f0022a07d6dd788d0 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Tue, 24 May 2022 13:38:21 -0500 Subject: [PATCH 6/7] Add SCSI_SENSE_MODE_FLEXABLE_GEOMETRY --- src/BlueSCSI.cpp | 9 +++++++++ src/scsi_sense.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index d7f0b83..66c0539 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -1291,6 +1291,15 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len) } a += 0x18; if(pageCode != SCSI_SENSE_MODE_ALL) break; + case SCSI_SENSE_MODE_FLEXABLE_GEOMETRY: + m_buf[a + 0] = SCSI_SENSE_MODE_FLEXABLE_GEOMETRY; + m_buf[a + 1] = 0x1E; // Page length + m_buf[a + 2] = 0x03E8; // Transfer rate 1 mbit/s + m_buf[a + 4] = 16; // Number of heads + m_buf[a + 5] = 18; // Sectors per track + m_buf[a + 6] = 0x2000; // Data bytes per sector + a += 0x1E; + if(pageCode != SCSI_SENSE_MODE_ALL) break; case SCSI_SENSE_MODE_VENDOR_APPLE: { const byte page30[0x14] = {0x41, 0x50, 0x50, 0x4C, 0x45, 0x20, 0x43, 0x4F, 0x4D, 0x50, 0x55, 0x54, 0x45, 0x52, 0x2C, 0x20, 0x49, 0x4E, 0x43, 0x20}; diff --git a/src/scsi_sense.h b/src/scsi_sense.h index 5a10218..3e4e812 100644 --- a/src/scsi_sense.h +++ b/src/scsi_sense.h @@ -37,6 +37,7 @@ #define SCSI_SENSE_MODE_DISCONNECT_RECONNECT 0x02 #define SCSI_SENSE_MODE_FORMAT_DEVICE 0x03 #define SCSI_SENSE_MODE_DISK_GEOMETRY 0x04 +#define SCSI_SENSE_MODE_FLEXABLE_GEOMETRY 0x05 #define SCSI_SENSE_MODE_VENDOR_APPLE 0x30 #define SCSI_SENSE_MODE_ALL 0x3F From 906b8be9aa979cf3c12ba9d43141cb44b6caf4b6 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Tue, 24 May 2022 16:45:50 -0500 Subject: [PATCH 7/7] Implement Send Diagnostic --- src/BlueSCSI.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index 66c0539..5342757 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -1468,6 +1468,27 @@ byte onReadBuffer(byte mode, uint32_t allocLength) } } +/* + * On Send Diagnostic + */ +byte onSendDiagnostic(byte flags) +{ + int self_test = flags & 0x4; + LOGN("-SendDiagnostic"); + LOGHEXN(flags); + if(self_test) + { + // Don't actually do a test, we're good. + return SCSI_STATUS_GOOD; + } + else + { + m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST; + m_addition_sense = SCSI_ASC_INVALID_FIELD_IN_CDB; + return SCSI_STATUS_CHECK_CONDITION; + } +} + /* * MsgIn2. */ @@ -1718,6 +1739,9 @@ void loop() LOGN("[ReadBuffer]"); m_sts |= onReadBuffer(cmd[1] & 7, ((uint32_t)cmd[6] << 16) | ((uint32_t)cmd[7] << 8) | cmd[8]); break; + case SCSI_SEND_DIAG: + m_sts |= onSendDiagnostic(cmd[1]); + break; default: LOGN("[*Unknown]"); m_sts |= SCSI_STATUS_CHECK_CONDITION;