From 19cc9ad169880d34f98bbdc79e1b7213557c8bd3 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Sat, 21 May 2022 13:18:37 -0500 Subject: [PATCH] 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