Merge pull request #114 from erichelgeson/eric/newCmds

Four new commands & some Sense
This commit is contained in:
Eric Helgeson 2022-05-25 02:38:02 +00:00 committed by GitHub
commit c2c3397b72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 247 additions and 63 deletions

View File

@ -32,13 +32,47 @@ 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-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
-DBOARD_RCC_PLLMUL=RCC_PLLMUL_12 #96000000L
# TODO: Find out why USB build flags get trampled when extending an extended env.
[env:STM32F1-USB]
extends = env:STM32F1
build_flags = ${env.build_flags}
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
@ -46,36 +80,17 @@ build_flags = ${env.build_flags}
-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\""
-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

View File

@ -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"
@ -54,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
@ -238,14 +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_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
@ -276,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;
@ -679,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");
@ -1239,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] = {
@ -1252,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
@ -1275,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);
@ -1288,19 +1290,28 @@ 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_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};
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;
@ -1334,10 +1345,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 +1367,127 @@ 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 && (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_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;
}
}
/*
* 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)
{
byte scsi_buf_response[SCSI_BUF_SIZE + 4];
// four byte read buffer header
scsi_buf_response[0] = 0;
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, SCSI_BUF_SIZE);
writeDataPhase(SCSI_BUF_SIZE + 4, scsi_buf_response);
#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;
}
}
/*
* 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.
@ -1521,8 +1655,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 +1731,17 @@ 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;
case SCSI_SEND_DIAG:
m_sts |= onSendDiagnostic(cmd[1]);
break;
default:
LOGN("[*Unknown]");
m_sts |= SCSI_STATUS_CHECK_CONDITION;

9
src/scsi_mode.h Normal file
View File

@ -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

View File

@ -29,4 +29,18 @@
#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_FLEXABLE_GEOMETRY 0x05
#define SCSI_SENSE_MODE_VENDOR_APPLE 0x30
#define SCSI_SENSE_MODE_ALL 0x3F
#endif