bluescsi.ini support enabled for some features
MegaSTE Mode Per SCSI device Product/Vendor/Revision bunch of text refactoring for brievity and byteshaving some reorg of the SD card info printed in the log other little bits here and there
This commit is contained in:
parent
c2c4b83925
commit
5bad53008a
273
src/BlueSCSI.cpp
273
src/BlueSCSI.cpp
|
@ -52,6 +52,7 @@
|
||||||
#include "scsi_sense.h"
|
#include "scsi_sense.h"
|
||||||
#include "scsi_status.h"
|
#include "scsi_status.h"
|
||||||
#include "scsi_mode.h"
|
#include "scsi_mode.h"
|
||||||
|
#include <minIni.h>
|
||||||
|
|
||||||
#ifdef USE_STM32_DMA
|
#ifdef USE_STM32_DMA
|
||||||
#warning "warning USE_STM32_DMA"
|
#warning "warning USE_STM32_DMA"
|
||||||
|
@ -64,16 +65,10 @@ FsFile LOG_FILE;
|
||||||
volatile bool m_isBusReset = false; // Bus reset
|
volatile bool m_isBusReset = false; // Bus reset
|
||||||
volatile bool m_resetJmp = false; // Call longjmp on reset
|
volatile bool m_resetJmp = false; // Call longjmp on reset
|
||||||
jmp_buf m_resetJmpBuf;
|
jmp_buf m_resetJmpBuf;
|
||||||
|
|
||||||
byte scsi_id_mask; // Mask list of responding SCSI IDs
|
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
|
|
||||||
byte m_buf[MAX_BLOCKSIZE]; // General purpose buffer
|
byte m_buf[MAX_BLOCKSIZE]; // General purpose buffer
|
||||||
byte m_scsi_buf[SCSI_BUF_SIZE]; // Buffer for SCSI READ/WRITE Buffer
|
byte m_scsi_buf[SCSI_BUF_SIZE]; // Buffer for SCSI READ/WRITE Buffer
|
||||||
unsigned m_scsi_buf_size = 0;
|
|
||||||
byte m_msb[256]; // Command storage bytes
|
|
||||||
SCSI_DEVICE scsi_device_list[NUM_SCSIID][NUM_SCSILUN]; // Maximum number
|
SCSI_DEVICE scsi_device_list[NUM_SCSIID][NUM_SCSILUN]; // Maximum number
|
||||||
SCSI_INQUIRY_DATA default_hdd, default_optical;
|
SCSI_INQUIRY_DATA default_hdd, default_optical;
|
||||||
|
|
||||||
|
@ -112,7 +107,7 @@ static void LBAtoMSF(const uint32_t lba, byte *msf);
|
||||||
|
|
||||||
static void flashError(const unsigned error);
|
static void flashError(const unsigned error);
|
||||||
void onBusReset(void);
|
void onBusReset(void);
|
||||||
void initFileLog(int);
|
void initFileLog(void);
|
||||||
void finalizeFileLog(void);
|
void finalizeFileLog(void);
|
||||||
void findDriveImages(FsFile root);
|
void findDriveImages(FsFile root);
|
||||||
|
|
||||||
|
@ -132,67 +127,106 @@ inline byte readIO(void)
|
||||||
return bret;
|
return bret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If config file exists, read the first three lines and copy the contents.
|
// Read config file for per device settings
|
||||||
// File must be well formed or you will get junk in the SCSI Vendor fields.
|
void readSCSIDeviceConfig(uint8_t scsi_id, SCSI_DEVICE *dev) {
|
||||||
void readSCSIDeviceConfig(SCSI_DEVICE *dev) {
|
SCSI_INQUIRY_DATA *iq = &dev->inquiry_block;
|
||||||
FsFile config_file = SD.open("scsi-config.txt", O_RDONLY);
|
char section[6] = {'S', 'C', 'S', 'I', 0, 0};
|
||||||
if (!config_file.isOpen()) {
|
FsFile config_file;
|
||||||
|
char *buf = (char *)&m_scsi_buf;
|
||||||
|
|
||||||
|
// check for bluescsi.ini
|
||||||
|
if(!SD.exists(BLUESCSI_INI)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SCSI_INQUIRY_DATA *iq = dev->inquiry_block;
|
|
||||||
|
|
||||||
char vendor[9];
|
// create section name from id
|
||||||
memset(vendor, 0, sizeof(vendor));
|
section[4] = INT_TO_CHAR(scsi_id);
|
||||||
config_file.readBytes(vendor, sizeof(vendor));
|
|
||||||
LOG_FILE.print("SCSI VENDOR: ");
|
|
||||||
LOG_FILE.println(vendor);
|
|
||||||
memcpy(&iq->vendor, vendor, 8);
|
|
||||||
|
|
||||||
char product[17];
|
switch(ini_getl(section, "type", 99, BLUESCSI_INI))
|
||||||
memset(product, 0, sizeof(product));
|
{
|
||||||
config_file.readBytes(product, sizeof(product));
|
case 0:
|
||||||
LOG_FILE.print("SCSI PRODUCT: ");
|
dev->m_type = SCSI_DEVICE_HDD;
|
||||||
LOG_FILE.println(product);
|
memcpy(iq, &default_hdd, sizeof(default_hdd));
|
||||||
memcpy(&iq->product, product, 16);
|
LOG_FILE.println("Forced HDD");
|
||||||
|
break;
|
||||||
|
|
||||||
char version[5];
|
case 2:
|
||||||
memset(version, 0, sizeof(version));
|
dev->m_type = SCSI_DEVICE_OPTICAL;
|
||||||
config_file.readBytes(version, sizeof(version));
|
memcpy(iq, &default_optical, sizeof(default_optical));
|
||||||
LOG_FILE.print("SCSI VERSION: ");
|
LOG_FILE.println("Forced Optical");
|
||||||
LOG_FILE.println(version);
|
break;
|
||||||
memcpy(&iq->revision, version, 4);
|
|
||||||
config_file.close();
|
case 99:
|
||||||
|
// default, do nothing at all
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_FILE.println("Unsupported override type");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ini_gets(section, "vendor", NULL, buf, SCSI_BUF_SIZE, BLUESCSI_INI)) {
|
||||||
|
memcpy(iq->vendor, buf, SCSI_VENDOR_LENGTH);
|
||||||
|
LOG_FILE.print("vendor:");
|
||||||
|
LOG_FILE.println(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ini_gets(section, "product", NULL, buf, SCSI_BUF_SIZE, BLUESCSI_INI)) {
|
||||||
|
memcpy(iq->product, buf, SCSI_PRODUCT_LENGTH);
|
||||||
|
LOG_FILE.print("product:");
|
||||||
|
LOG_FILE.println(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ini_gets(section, "revision", NULL, buf, SCSI_BUF_SIZE, BLUESCSI_INI)) {
|
||||||
|
memcpy(iq->revision, buf, SCSI_REVISION_LENGTH);
|
||||||
|
LOG_FILE.print("revision:");
|
||||||
|
LOG_FILE.println(buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read SD information and print to logfile
|
// read SD information and print to logfile
|
||||||
void readSDCardInfo()
|
void readSDCardInfo(int success_mhz)
|
||||||
{
|
{
|
||||||
cid_t sd_cid;
|
cid_t sd_cid;
|
||||||
|
|
||||||
|
LOG_FILE.println("SDCard Info:");
|
||||||
|
LOG_FILE.print(" Format:");
|
||||||
|
switch(SD.vol()->fatType()) {
|
||||||
|
case FAT_TYPE_EXFAT:
|
||||||
|
LOG_FILE.println("exFAT");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FILE.print("FAT32/16/12 - exFAT may improve performance");
|
||||||
|
}
|
||||||
|
LOG_FILE.print("SPI speed: ");
|
||||||
|
LOG_FILE.print(success_mhz);
|
||||||
|
LOG_FILE.println("Mhz");
|
||||||
|
LOG_FILE.print(" Max Filename Length:");
|
||||||
|
LOG_FILE.println(MAX_FILE_PATH);
|
||||||
|
|
||||||
if(SD.card()->readCID(&sd_cid))
|
if(SD.card()->readCID(&sd_cid))
|
||||||
{
|
{
|
||||||
LOG_FILE.print("Sd MID:");
|
LOG_FILE.print(" MID:");
|
||||||
LOG_FILE.print(sd_cid.mid, 16);
|
LOG_FILE.print(sd_cid.mid, 16);
|
||||||
LOG_FILE.print(" OID:");
|
LOG_FILE.print(" OID:");
|
||||||
LOG_FILE.print(sd_cid.oid[0]);
|
LOG_FILE.print(sd_cid.oid[0]);
|
||||||
LOG_FILE.println(sd_cid.oid[1]);
|
LOG_FILE.println(sd_cid.oid[1]);
|
||||||
|
|
||||||
LOG_FILE.print("Sd Name:");
|
LOG_FILE.print(" Name:");
|
||||||
LOG_FILE.print(sd_cid.pnm[0]);
|
LOG_FILE.print(sd_cid.pnm[0]);
|
||||||
LOG_FILE.print(sd_cid.pnm[1]);
|
LOG_FILE.print(sd_cid.pnm[1]);
|
||||||
LOG_FILE.print(sd_cid.pnm[2]);
|
LOG_FILE.print(sd_cid.pnm[2]);
|
||||||
LOG_FILE.print(sd_cid.pnm[3]);
|
LOG_FILE.print(sd_cid.pnm[3]);
|
||||||
LOG_FILE.println(sd_cid.pnm[4]);
|
LOG_FILE.print(sd_cid.pnm[4]);
|
||||||
|
|
||||||
LOG_FILE.print("Sd Date:");
|
LOG_FILE.print(" Date:");
|
||||||
LOG_FILE.print(sd_cid.mdtMonth());
|
LOG_FILE.print(sd_cid.mdtMonth());
|
||||||
LOG_FILE.print("/");
|
LOG_FILE.print("/");
|
||||||
LOG_FILE.println(sd_cid.mdtYear());
|
LOG_FILE.println(sd_cid.mdtYear());
|
||||||
|
|
||||||
LOG_FILE.print("Sd Serial:");
|
LOG_FILE.print(" Serial:");
|
||||||
LOG_FILE.println(sd_cid.psn());
|
LOG_FILE.println(sd_cid.psn());
|
||||||
LOG_FILE.sync();
|
|
||||||
}
|
}
|
||||||
|
LOG_FILE.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VerifyISOPVD(SCSI_DEVICE *dev, unsigned sector_size, bool mode2)
|
bool VerifyISOPVD(SCSI_DEVICE *dev, unsigned sector_size, bool mode2)
|
||||||
|
@ -202,13 +236,13 @@ bool VerifyISOPVD(SCSI_DEVICE *dev, unsigned sector_size, bool mode2)
|
||||||
if(mode2) seek += 8;
|
if(mode2) seek += 8;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
dev->m_file->seekSet(seek);
|
dev->m_file.seekSet(seek);
|
||||||
dev->m_file->read(m_buf, 2048);
|
dev->m_file.read(m_buf, 2048);
|
||||||
|
|
||||||
ret = ((m_buf[0] == 1 && !strncmp((char *)&m_buf[1], "CD001", 5) && m_buf[6] == 1) ||
|
ret = ((m_buf[0] == 1 && !strncmp((char *)&m_buf[1], "CD001", 5) && m_buf[6] == 1) ||
|
||||||
(m_buf[8] == 1 && !strncmp((char *)&m_buf[9], "CDROM", 5) && m_buf[14] == 1));
|
(m_buf[8] == 1 && !strncmp((char *)&m_buf[9], "CDROM", 5) && m_buf[14] == 1));
|
||||||
|
|
||||||
dev->m_file->rewind();
|
dev->m_file.rewind();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,18 +254,19 @@ bool hddimageOpen(SCSI_DEVICE *dev, FsFile *file,int id,int lun,int blocksize)
|
||||||
{
|
{
|
||||||
dev->m_fileSize= 0;
|
dev->m_fileSize= 0;
|
||||||
dev->m_sector_offset = 0;
|
dev->m_sector_offset = 0;
|
||||||
|
dev->flags = 0;
|
||||||
dev->m_blocksize = blocksize;
|
dev->m_blocksize = blocksize;
|
||||||
dev->m_rawblocksize = blocksize;
|
dev->m_rawblocksize = blocksize;
|
||||||
dev->m_file = file;
|
dev->m_file = *file;
|
||||||
if(!dev->m_file->isOpen()) { goto failed; }
|
if(!dev->m_file.isOpen()) { goto failed; }
|
||||||
|
|
||||||
dev->m_fileSize = dev->m_file->size();
|
dev->m_fileSize = dev->m_file.size();
|
||||||
|
|
||||||
if(dev->m_fileSize < 1) {
|
if(dev->m_fileSize < 1) {
|
||||||
LOG_FILE.println(" - file is 0 bytes, can not use.");
|
LOG_FILE.println(" - file is 0 bytes, can not use.");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
if(!dev->m_file->isContiguous())
|
if(!dev->m_file.isContiguous())
|
||||||
{
|
{
|
||||||
LOG_FILE.println(" - file is fragmented, see https://github.com/erichelgeson/BlueSCSI/wiki/Image-File-Fragmentation");
|
LOG_FILE.println(" - file is fragmented, see https://github.com/erichelgeson/BlueSCSI/wiki/Image-File-Fragmentation");
|
||||||
}
|
}
|
||||||
|
@ -243,19 +278,18 @@ bool hddimageOpen(SCSI_DEVICE *dev, FsFile *file,int id,int lun,int blocksize)
|
||||||
// Borrowed from PCEM
|
// Borrowed from PCEM
|
||||||
if(VerifyISOPVD(dev, CDROM_COMMON_SECTORSIZE, false)) {
|
if(VerifyISOPVD(dev, CDROM_COMMON_SECTORSIZE, false)) {
|
||||||
dev->m_rawblocksize = CDROM_COMMON_SECTORSIZE;
|
dev->m_rawblocksize = CDROM_COMMON_SECTORSIZE;
|
||||||
dev->m_mode2 = false;
|
SET_DEVICE_FLAG(dev->flags, SCSI_DEVICE_FLAG_OPTICAL_MODE2);
|
||||||
} else if(VerifyISOPVD(dev, CDROM_RAW_SECTORSIZE, false)) {
|
} else if(VerifyISOPVD(dev, CDROM_RAW_SECTORSIZE, false)) {
|
||||||
dev->m_rawblocksize = CDROM_RAW_SECTORSIZE;
|
dev->m_rawblocksize = CDROM_RAW_SECTORSIZE;
|
||||||
dev->m_mode2 = false;
|
SET_DEVICE_FLAG(dev->flags, SCSI_DEVICE_FLAG_OPTICAL_RAW);
|
||||||
dev->m_raw = true;
|
|
||||||
dev->m_sector_offset = 16;
|
dev->m_sector_offset = 16;
|
||||||
} else if(VerifyISOPVD(dev, 2336, true)) {
|
} else if(VerifyISOPVD(dev, 2336, true)) {
|
||||||
dev->m_rawblocksize = 2336;
|
dev->m_rawblocksize = 2336;
|
||||||
dev->m_mode2 = true;
|
SET_DEVICE_FLAG(dev->flags, SCSI_DEVICE_FLAG_OPTICAL_MODE2);
|
||||||
} else if(VerifyISOPVD(dev, CDROM_RAW_SECTORSIZE, true)) {
|
} else if(VerifyISOPVD(dev, CDROM_RAW_SECTORSIZE, true)) {
|
||||||
dev->m_rawblocksize = CDROM_RAW_SECTORSIZE;
|
dev->m_rawblocksize = CDROM_RAW_SECTORSIZE;
|
||||||
dev->m_mode2 = true;
|
SET_DEVICE_FLAG(dev->flags, SCSI_DEVICE_FLAG_OPTICAL_MODE2);
|
||||||
dev->m_raw = true;
|
SET_DEVICE_FLAG(dev->flags, SCSI_DEVICE_FLAG_OPTICAL_RAW);
|
||||||
dev->m_sector_offset = 24;
|
dev->m_sector_offset = 24;
|
||||||
} else {
|
} else {
|
||||||
// Last ditch effort
|
// Last ditch effort
|
||||||
|
@ -264,7 +298,7 @@ bool hddimageOpen(SCSI_DEVICE *dev, FsFile *file,int id,int lun,int blocksize)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->m_raw = true;
|
SET_DEVICE_FLAG(dev->flags, SCSI_DEVICE_FLAG_OPTICAL_RAW);
|
||||||
|
|
||||||
if(!(dev->m_fileSize % CDROM_COMMON_SECTORSIZE)) {
|
if(!(dev->m_fileSize % CDROM_COMMON_SECTORSIZE)) {
|
||||||
// try a multiple of 2048
|
// try a multiple of 2048
|
||||||
|
@ -291,17 +325,17 @@ bool hddimageOpen(SCSI_DEVICE *dev, FsFile *file,int id,int lun,int blocksize)
|
||||||
LOG_FILE.println("MiB");
|
LOG_FILE.println("MiB");
|
||||||
|
|
||||||
if(dev->m_type == SCSI_DEVICE_OPTICAL) {
|
if(dev->m_type == SCSI_DEVICE_OPTICAL) {
|
||||||
LOG_FILE.print(" MODE2:");LOG_FILE.print(dev->m_mode2);
|
LOG_FILE.print(" MODE2:");LOG_FILE.print(IS_MODE2(dev->flags));
|
||||||
LOG_FILE.print(" BlockSize:");LOG_FILE.println(dev->m_rawblocksize);
|
LOG_FILE.print(" BlockSize:");LOG_FILE.println(IS_RAW(dev->flags));
|
||||||
}
|
}
|
||||||
return true; // File opened
|
return true; // File opened
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
|
||||||
dev->m_file->close();
|
dev->m_file.close();
|
||||||
dev->m_fileSize = dev->m_blocksize = 0; // no file
|
dev->m_fileSize = dev->m_blocksize = 0; // no file
|
||||||
delete dev->m_file;
|
//delete dev->m_file;
|
||||||
dev->m_file = NULL;
|
//dev->m_file = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,15 +360,6 @@ void setup()
|
||||||
scsi_command_table[i] = onUnimplemented;
|
scsi_command_table[i] = onUnimplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
// zero all SCSI device structs
|
|
||||||
for(unsigned id = 0; id < NUM_SCSIID; id++)
|
|
||||||
{
|
|
||||||
for(unsigned lun = 0; lun < NUM_SCSILUN; lun++)
|
|
||||||
{
|
|
||||||
memset(&scsi_device_list[id][lun], 0, sizeof(SCSI_DEVICE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SCSI commands that just need to return ok
|
// SCSI commands that just need to return ok
|
||||||
scsi_command_table[SCSI_FORMAT_UNIT4] = onNOP;
|
scsi_command_table[SCSI_FORMAT_UNIT4] = onNOP;
|
||||||
scsi_command_table[SCSI_FORMAT_UNIT6] = onNOP;
|
scsi_command_table[SCSI_FORMAT_UNIT6] = onNOP;
|
||||||
|
@ -483,22 +508,26 @@ void setup()
|
||||||
|
|
||||||
if(!sd_ready) {
|
if(!sd_ready) {
|
||||||
#if DEBUG > 0
|
#if DEBUG > 0
|
||||||
Serial.println("SD initialization failed!");
|
Serial.println("SD Init failed!");
|
||||||
#endif
|
#endif
|
||||||
flashError(ERROR_NO_SDCARD);
|
flashError(ERROR_NO_SDCARD);
|
||||||
}
|
}
|
||||||
initFileLog(mhz);
|
initFileLog();
|
||||||
readSDCardInfo();
|
readSDCardInfo(mhz);
|
||||||
|
|
||||||
//HD image file open
|
//HD image file open
|
||||||
scsi_id_mask = 0x00;
|
scsi_id_mask = 0x00;
|
||||||
|
|
||||||
// Look for this file to enable MSTE_MODE
|
if(ini_getl("SCSI", "megastemode", 0, BLUESCSI_INI))
|
||||||
if(SD.exists("MSTE_MODE")) {
|
{
|
||||||
LOG_FILE.println("MSTE_MODE - IDs treated as LUNs");
|
LOG_FILE.println("MSTE_MODE - IDs treated as LUNs");
|
||||||
megaste_mode = true;
|
megaste_mode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(SD.exists("scsi-config.txt")) {
|
||||||
|
LOG_FILE.println("scsi-config.txt is deprecated, use bluescsi.ini");
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate over the root path in the SD card looking for candidate image files.
|
// Iterate over the root path in the SD card looking for candidate image files.
|
||||||
FsFile root;
|
FsFile root;
|
||||||
|
|
||||||
|
@ -540,7 +569,7 @@ void setup()
|
||||||
|
|
||||||
void findDriveImages(FsFile root) {
|
void findDriveImages(FsFile root) {
|
||||||
bool image_ready;
|
bool image_ready;
|
||||||
FsFile *file = NULL;
|
FsFile file;
|
||||||
char path_name[MAX_FILE_PATH+1];
|
char path_name[MAX_FILE_PATH+1];
|
||||||
root.getName(path_name, sizeof(path_name));
|
root.getName(path_name, sizeof(path_name));
|
||||||
SD.chdir(path_name);
|
SD.chdir(path_name);
|
||||||
|
@ -564,14 +593,11 @@ void findDriveImages(FsFile root) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valid file, open for reading/writing.
|
// Valid file, open for reading/writing.
|
||||||
file = new FsFile(SD.open(name, O_RDWR));
|
file = SD.open(name, O_RDWR);
|
||||||
if(file && file->isFile()) {
|
if(file && file.isFile()) {
|
||||||
SCSI_DEVICE_TYPE device_type;
|
SCSI_DEVICE_TYPE device_type;
|
||||||
if(tolower(name[1]) != 'd') {
|
if(tolower(name[1]) != 'd') {
|
||||||
file->close();
|
file.close();
|
||||||
delete file;
|
|
||||||
LOG_FILE.print("Not an image: ");
|
|
||||||
LOG_FILE.println(name);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,10 +607,7 @@ void findDriveImages(FsFile root) {
|
||||||
case 'c': device_type = SCSI_DEVICE_OPTICAL;
|
case 'c': device_type = SCSI_DEVICE_OPTICAL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
file->close();
|
file.close();
|
||||||
delete file;
|
|
||||||
LOG_FILE.print("Not an image: ");
|
|
||||||
LOG_FILE.println(name);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,7 +620,7 @@ void findDriveImages(FsFile root) {
|
||||||
// We only require the minimum and read in the next if provided.
|
// We only require the minimum and read in the next if provided.
|
||||||
int file_name_length = strlen(name);
|
int file_name_length = strlen(name);
|
||||||
if(file_name_length > 2) { // HD[N]
|
if(file_name_length > 2) { // HD[N]
|
||||||
int tmp_id = name[HDIMG_ID_POS] - '0';
|
int tmp_id = CHAR_TO_INT(name[HDIMG_ID_POS]);
|
||||||
|
|
||||||
// If valid id, set it, else use default
|
// If valid id, set it, else use default
|
||||||
if(tmp_id > -1 && tmp_id < 8) {
|
if(tmp_id > -1 && tmp_id < 8) {
|
||||||
|
@ -609,7 +632,7 @@ void findDriveImages(FsFile root) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(file_name_length > 3) { // HDN[N]
|
if(file_name_length > 3) { // HDN[N]
|
||||||
int tmp_lun = name[HDIMG_LUN_POS] - '0';
|
int tmp_lun = CHAR_TO_INT(name[HDIMG_LUN_POS]);
|
||||||
|
|
||||||
// If valid lun, set it, else use default
|
// If valid lun, set it, else use default
|
||||||
if(tmp_lun == 0 || tmp_lun == 1) {
|
if(tmp_lun == 0 || tmp_lun == 1) {
|
||||||
|
@ -622,11 +645,11 @@ void findDriveImages(FsFile root) {
|
||||||
|
|
||||||
int blk1 = 0, blk2, blk3, blk4 = 0;
|
int blk1 = 0, blk2, blk3, blk4 = 0;
|
||||||
if(file_name_length > 8) { // HD00_[111]
|
if(file_name_length > 8) { // HD00_[111]
|
||||||
blk1 = name[HDIMG_BLK_POS] - '0';
|
blk1 = CHAR_TO_INT(name[HDIMG_BLK_POS]);
|
||||||
blk2 = name[HDIMG_BLK_POS+1] - '0';
|
blk2 = CHAR_TO_INT(name[HDIMG_BLK_POS+1]);
|
||||||
blk3 = name[HDIMG_BLK_POS+2] - '0';
|
blk3 = CHAR_TO_INT(name[HDIMG_BLK_POS+2]);
|
||||||
if(file_name_length > 9) // HD00_NNN[1]
|
if(file_name_length > 9) // HD00_NNN[1]
|
||||||
blk4 = name[HDIMG_BLK_POS+3] - '0';
|
blk4 = CHAR_TO_INT(name[HDIMG_BLK_POS+3]);
|
||||||
}
|
}
|
||||||
if(blk1 == 2 && blk2 == 5 && blk3 == 6) {
|
if(blk1 == 2 && blk2 == 5 && blk3 == 6) {
|
||||||
blk = 256;
|
blk = 256;
|
||||||
|
@ -641,7 +664,7 @@ void findDriveImages(FsFile root) {
|
||||||
LOG_FILE.print(" - ");
|
LOG_FILE.print(" - ");
|
||||||
LOG_FILE.print(name);
|
LOG_FILE.print(name);
|
||||||
dev->m_type = device_type;
|
dev->m_type = device_type;
|
||||||
image_ready = hddimageOpen(dev, file, id, lun, blk);
|
image_ready = hddimageOpen(dev, &file, id, lun, blk);
|
||||||
if(image_ready) { // Marked as a responsive ID
|
if(image_ready) { // Marked as a responsive ID
|
||||||
scsi_id_mask |= 1<<id;
|
scsi_id_mask |= 1<<id;
|
||||||
|
|
||||||
|
@ -649,16 +672,16 @@ void findDriveImages(FsFile root) {
|
||||||
{
|
{
|
||||||
case SCSI_DEVICE_HDD:
|
case SCSI_DEVICE_HDD:
|
||||||
// default SCSI HDD
|
// default SCSI HDD
|
||||||
dev->inquiry_block = &default_hdd;
|
dev->inquiry_block = default_hdd;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCSI_DEVICE_OPTICAL:
|
case SCSI_DEVICE_OPTICAL:
|
||||||
// default SCSI CDROM
|
// default SCSI CDROM
|
||||||
dev->inquiry_block = &default_optical;
|
dev->inquiry_block = default_optical;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
readSCSIDeviceConfig(dev);
|
readSCSIDeviceConfig(id, dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -671,32 +694,14 @@ void findDriveImages(FsFile root) {
|
||||||
/*
|
/*
|
||||||
* Setup initialization logfile
|
* Setup initialization logfile
|
||||||
*/
|
*/
|
||||||
void initFileLog(int success_mhz) {
|
void initFileLog() {
|
||||||
LOG_FILE = SD.open(LOG_FILENAME, O_WRONLY | O_CREAT | O_TRUNC);
|
LOG_FILE = SD.open(LOG_FILENAME, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
LOG_FILE.println("BlueSCSI <-> SD - https://github.com/erichelgeson/BlueSCSI");
|
LOG_FILE.println("BlueSCSI https://github.com/erichelgeson/BlueSCSI");
|
||||||
LOG_FILE.print("VER: ");
|
LOG_FILE.print("VER: ");
|
||||||
LOG_FILE.print(VERSION);
|
LOG_FILE.print(VERSION);
|
||||||
LOG_FILE.println(BUILD_TAGS);
|
LOG_FILE.println(BUILD_TAGS);
|
||||||
LOG_FILE.print("DEBUG:");
|
LOG_FILE.print("DEBUG:");
|
||||||
LOG_FILE.print(DEBUG);
|
LOG_FILE.println(DEBUG);
|
||||||
LOG_FILE.print(" SDFAT_FILE_TYPE:");
|
|
||||||
LOG_FILE.println(SDFAT_FILE_TYPE);
|
|
||||||
LOG_FILE.print("SdFat version: ");
|
|
||||||
LOG_FILE.println(SD_FAT_VERSION_STR);
|
|
||||||
LOG_FILE.print("Sd Format: ");
|
|
||||||
switch(SD.vol()->fatType()) {
|
|
||||||
case FAT_TYPE_EXFAT:
|
|
||||||
LOG_FILE.println("exFAT");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_FILE.print("FAT 32/16/12 - Consider formatting the SD Card with exFAT for improved performance.");
|
|
||||||
}
|
|
||||||
LOG_FILE.print("SPI speed: ");
|
|
||||||
LOG_FILE.print(success_mhz);
|
|
||||||
LOG_FILE.println("Mhz");
|
|
||||||
LOG_FILE.print("SdFat Max FileName Length: ");
|
|
||||||
LOG_FILE.println(MAX_FILE_PATH);
|
|
||||||
LOG_FILE.println("Initialized SD Card - let's go!");
|
|
||||||
LOG_FILE.sync();
|
LOG_FILE.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,7 +735,7 @@ void finalizeFileLog() {
|
||||||
}
|
}
|
||||||
LOG_FILE.println(":");
|
LOG_FILE.println(":");
|
||||||
}
|
}
|
||||||
LOG_FILE.println("Finished initialization of SCSI Devices - Entering main loop.");
|
LOG_FILE.println("Finished configuration - Starting BlueSCSI");
|
||||||
LOG_FILE.sync();
|
LOG_FILE.sync();
|
||||||
#if DEBUG < 2
|
#if DEBUG < 2
|
||||||
LOG_FILE.close();
|
LOG_FILE.close();
|
||||||
|
@ -948,7 +953,7 @@ void writeDataPhaseSD(SCSI_DEVICE *dev, uint32_t adds, uint32_t len)
|
||||||
SCSI_PHASE_CHANGE(SCSI_PHASE_DATAIN);
|
SCSI_PHASE_CHANGE(SCSI_PHASE_DATAIN);
|
||||||
//Bus settle delay 400ns, file.seek() measured at over 1000ns.
|
//Bus settle delay 400ns, file.seek() measured at over 1000ns.
|
||||||
uint64_t pos = (uint64_t)adds * dev->m_rawblocksize;
|
uint64_t pos = (uint64_t)adds * dev->m_rawblocksize;
|
||||||
dev->m_file->seekSet(pos);
|
dev->m_file.seekSet(pos);
|
||||||
#ifdef XCVR
|
#ifdef XCVR
|
||||||
TRANSCEIVER_IO_SET(vTR_DBP,TR_OUTPUT)
|
TRANSCEIVER_IO_SET(vTR_DBP,TR_OUTPUT)
|
||||||
#endif
|
#endif
|
||||||
|
@ -957,7 +962,7 @@ void writeDataPhaseSD(SCSI_DEVICE *dev, uint32_t adds, uint32_t len)
|
||||||
for(uint32_t i = 0; i < len; i++) {
|
for(uint32_t i = 0; i < len; i++) {
|
||||||
// Asynchronous reads will make it faster ...
|
// Asynchronous reads will make it faster ...
|
||||||
m_resetJmp = false;
|
m_resetJmp = false;
|
||||||
dev->m_file->read(m_buf, dev->m_rawblocksize);
|
dev->m_file.read(m_buf, dev->m_rawblocksize);
|
||||||
enableResetJmp();
|
enableResetJmp();
|
||||||
|
|
||||||
writeDataLoop(dev->m_blocksize, &m_buf[dev->m_sector_offset]);
|
writeDataLoop(dev->m_blocksize, &m_buf[dev->m_sector_offset]);
|
||||||
|
@ -1029,18 +1034,18 @@ void readDataPhaseSD(SCSI_DEVICE *dev, uint32_t adds, uint32_t len)
|
||||||
//Bus settle delay 400ns, file.seek() measured at over 1000ns.
|
//Bus settle delay 400ns, file.seek() measured at over 1000ns.
|
||||||
|
|
||||||
uint64_t pos = (uint64_t)adds * dev->m_blocksize;
|
uint64_t pos = (uint64_t)adds * dev->m_blocksize;
|
||||||
dev->m_file->seekSet(pos);
|
dev->m_file.seekSet(pos);
|
||||||
for(uint32_t i = 0; i < len; i++) {
|
for(uint32_t i = 0; i < len; i++) {
|
||||||
m_resetJmp = true;
|
m_resetJmp = true;
|
||||||
readDataLoop(dev->m_blocksize, m_buf);
|
readDataLoop(dev->m_blocksize, m_buf);
|
||||||
m_resetJmp = false;
|
m_resetJmp = false;
|
||||||
dev->m_file->write(m_buf, dev->m_blocksize);
|
dev->m_file.write(m_buf, dev->m_blocksize);
|
||||||
// If a reset happened while writing, break and let the flush happen before it is handled.
|
// If a reset happened while writing, break and let the flush happen before it is handled.
|
||||||
if (m_isBusReset) {
|
if (m_isBusReset) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dev->m_file->flush();
|
dev->m_file.flush();
|
||||||
enableResetJmp();
|
enableResetJmp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1055,7 +1060,7 @@ void verifyDataPhaseSD(SCSI_DEVICE *dev, uint32_t adds, uint32_t len)
|
||||||
//Bus settle delay 400ns, file.seek() measured at over 1000ns.
|
//Bus settle delay 400ns, file.seek() measured at over 1000ns.
|
||||||
|
|
||||||
uint64_t pos = (uint64_t)adds * dev->m_blocksize;
|
uint64_t pos = (uint64_t)adds * dev->m_blocksize;
|
||||||
dev->m_file->seekSet(pos);
|
dev->m_file.seekSet(pos);
|
||||||
for(uint32_t i = 0; i < len; i++) {
|
for(uint32_t i = 0; i < len; i++) {
|
||||||
readDataLoop(dev->m_blocksize, m_buf);
|
readDataLoop(dev->m_blocksize, m_buf);
|
||||||
// This has just gone through the transfer to make things work, a compare would go here.
|
// This has just gone through the transfer to make things work, a compare would go here.
|
||||||
|
@ -1079,6 +1084,12 @@ void MsgIn2(int msg)
|
||||||
*/
|
*/
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
|
byte m_id = 0; // Currently responding SCSI-ID
|
||||||
|
byte m_lun = 0xff; // Logical unit number currently responding
|
||||||
|
byte m_sts = 0; // Status byte
|
||||||
|
byte m_msg = 0; // Message bytes
|
||||||
|
byte m_msb[256]; // Command storage bytes
|
||||||
|
|
||||||
#ifdef XCVR
|
#ifdef XCVR
|
||||||
// Reset all DB and Target pins, switch transceivers to input
|
// Reset all DB and Target pins, switch transceivers to input
|
||||||
// Precaution against bugs or jumps which don't clean up properly
|
// Precaution against bugs or jumps which don't clean up properly
|
||||||
|
@ -1088,9 +1099,6 @@ void loop()
|
||||||
TRANSCEIVER_IO_SET(vTR_INITIATOR,TR_INPUT)
|
TRANSCEIVER_IO_SET(vTR_INITIATOR,TR_INPUT)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//int msg = 0;
|
|
||||||
m_msg = 0;
|
|
||||||
m_lun = 0xff;
|
|
||||||
SCSI_DEVICE *dev = (SCSI_DEVICE *)0; // HDD image for current SCSI-ID, LUN
|
SCSI_DEVICE *dev = (SCSI_DEVICE *)0; // HDD image for current SCSI-ID, LUN
|
||||||
|
|
||||||
do {} while( SCSI_IN(vBSY) || !SCSI_IN(vSEL) || SCSI_IN(vRST));
|
do {} while( SCSI_IN(vBSY) || !SCSI_IN(vSEL) || SCSI_IN(vRST));
|
||||||
|
@ -1255,16 +1263,16 @@ void loop()
|
||||||
LOGN("onInquiry - InvalidLUN");
|
LOGN("onInquiry - InvalidLUN");
|
||||||
dev = &(scsi_device_list[m_id][0]);
|
dev = &(scsi_device_list[m_id][0]);
|
||||||
|
|
||||||
byte temp = dev->inquiry_block->raw[0];
|
byte temp = dev->inquiry_block.raw[0];
|
||||||
|
|
||||||
// If the LUN is invalid byte 0 of inquiry block needs to be 7fh
|
// If the LUN is invalid byte 0 of inquiry block needs to be 7fh
|
||||||
dev->inquiry_block->raw[0] = 0x7f;
|
dev->inquiry_block.raw[0] = 0x7f;
|
||||||
|
|
||||||
// only write back what was asked for
|
// only write back what was asked for
|
||||||
writeDataPhase(cmd[4], dev->inquiry_block->raw);
|
writeDataPhase(cmd[4], dev->inquiry_block.raw);
|
||||||
|
|
||||||
// return it back to normal if it was altered
|
// return it back to normal if it was altered
|
||||||
dev->inquiry_block->raw[0] = temp;
|
dev->inquiry_block.raw[0] = temp;
|
||||||
}
|
}
|
||||||
else if(cmd[0] == SCSI_REQUEST_SENSE)
|
else if(cmd[0] == SCSI_REQUEST_SENSE)
|
||||||
{
|
{
|
||||||
|
@ -1290,7 +1298,7 @@ void loop()
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = &(scsi_device_list[m_id][m_lun]);
|
dev = &(scsi_device_list[m_id][m_lun]);
|
||||||
if(!dev->m_file)
|
if(!dev->m_file.isOpen())
|
||||||
{
|
{
|
||||||
dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
|
dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
|
||||||
dev->m_additional_sense_code = SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED;
|
dev->m_additional_sense_code = SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED;
|
||||||
|
@ -1359,7 +1367,7 @@ static byte onNOP(SCSI_DEVICE *dev, const byte *cdb)
|
||||||
*/
|
*/
|
||||||
byte onInquiry(SCSI_DEVICE *dev, const byte *cdb)
|
byte onInquiry(SCSI_DEVICE *dev, const byte *cdb)
|
||||||
{
|
{
|
||||||
writeDataPhase(cdb[4] < 47 ? cdb[4] : 47, dev->inquiry_block->raw);
|
writeDataPhase(cdb[4] < 47 ? cdb[4] : 47, dev->inquiry_block.raw);
|
||||||
return SCSI_STATUS_GOOD;
|
return SCSI_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1891,7 +1899,7 @@ byte onWriteBuffer(SCSI_DEVICE *dev, const byte *cdb)
|
||||||
byte onReadBuffer(SCSI_DEVICE *dev, const byte *cdb)
|
byte onReadBuffer(SCSI_DEVICE *dev, const byte *cdb)
|
||||||
{
|
{
|
||||||
byte mode = cdb[1] & 7;
|
byte mode = cdb[1] & 7;
|
||||||
uint32_t allocLength = ((uint32_t)cdb[6] << 16) | ((uint32_t)cdb[7] << 8) | cdb[8];
|
unsigned m_scsi_buf_size = 0;
|
||||||
|
|
||||||
LOGN("-ReadBuffer");
|
LOGN("-ReadBuffer");
|
||||||
LOGHEXN(mode);
|
LOGHEXN(mode);
|
||||||
|
@ -1911,6 +1919,7 @@ byte onReadBuffer(SCSI_DEVICE *dev, const byte *cdb)
|
||||||
writeDataPhase(4 + m_scsi_buf_size, m_buf);
|
writeDataPhase(4 + m_scsi_buf_size, m_buf);
|
||||||
|
|
||||||
#if DEBUG > 0
|
#if DEBUG > 0
|
||||||
|
uint32_t allocLength = ((uint32_t)cdb[6] << 16) | ((uint32_t)cdb[7] << 8) | cdb[8];
|
||||||
for (unsigned i = 0; i < allocLength; i++) {
|
for (unsigned i = 0; i < allocLength; i++) {
|
||||||
LOGHEX(m_scsi_buf[i]);LOG(" ");
|
LOGHEX(m_scsi_buf[i]);LOG(" ");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,11 @@
|
||||||
#define SCSI_BUF_SIZE 512 // Size of the SCSI Buffer
|
#define SCSI_BUF_SIZE 512 // Size of the SCSI Buffer
|
||||||
#define HDD_BLOCK_SIZE 512
|
#define HDD_BLOCK_SIZE 512
|
||||||
#define OPTICAL_BLOCK_SIZE 2048
|
#define OPTICAL_BLOCK_SIZE 2048
|
||||||
|
#define BLUESCSI_INI "bluescsi.ini"
|
||||||
|
|
||||||
|
#define SCSI_VENDOR_LENGTH 8
|
||||||
|
#define SCSI_PRODUCT_LENGTH 16
|
||||||
|
#define SCSI_REVISION_LENGTH 4
|
||||||
|
|
||||||
// HDD format
|
// HDD format
|
||||||
#define MAX_BLOCKSIZE 4096 // Maximum BLOCK size
|
#define MAX_BLOCKSIZE 4096 // Maximum BLOCK size
|
||||||
|
@ -32,6 +37,18 @@ enum SCSI_DEVICE_TYPE
|
||||||
SCSI_DEVICE_OPTICAL,
|
SCSI_DEVICE_OPTICAL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SCSI_DEVICE_FLAG_OPTICAL_MODE2 0x1
|
||||||
|
#define SCSI_DEVICE_FLAG_OPTICAL_RAW 0x2
|
||||||
|
|
||||||
|
#define SET_DEVICE_FLAG(var, flag) (var |= flag)
|
||||||
|
#define UNSET_DEVICE_FLAG(var, flag) (var &= ~flag)
|
||||||
|
#define IS_DEVICE_FLAG_SET(var, flag) ((var & flag) == flag)
|
||||||
|
#define IS_RAW(var) IS_DEVICE_FLAG_SET(var, SCSI_DEVICE_FLAG_OPTICAL_RAW)
|
||||||
|
#define IS_MODE2(var) IS_DEVICE_FLAG_SET(var, SCSI_DEVICE_FLAG_OPTICAL_MODE2)
|
||||||
|
|
||||||
|
#define INT_TO_CHAR(var) var+'0'
|
||||||
|
#define CHAR_TO_INT(var) var-'0'
|
||||||
|
|
||||||
#define CDROM_RAW_SECTORSIZE 2352
|
#define CDROM_RAW_SECTORSIZE 2352
|
||||||
#define CDROM_COMMON_SECTORSIZE 2048
|
#define CDROM_COMMON_SECTORSIZE 2048
|
||||||
|
|
||||||
|
@ -124,7 +141,7 @@ enum SCSI_DEVICE_TYPE
|
||||||
// SCSI output pin control: opendrain active LOW (direct pin drive)
|
// SCSI output pin control: opendrain active LOW (direct pin drive)
|
||||||
#define SCSI_OUT(VPIN,ACTIVE) { GPIOREG(VPIN)->BSRR = BITMASK(VPIN)<<((ACTIVE)?16:0); }
|
#define SCSI_OUT(VPIN,ACTIVE) { GPIOREG(VPIN)->BSRR = BITMASK(VPIN)<<((ACTIVE)?16:0); }
|
||||||
|
|
||||||
// SCSI input pin check (inactive=0,avtive=1)
|
// SCSI input pin check (inactive=0,active=1)
|
||||||
#define SCSI_IN(VPIN) ((~GPIOREG(VPIN)->IDR>>(VPIN&15))&1)
|
#define SCSI_IN(VPIN) ((~GPIOREG(VPIN)->IDR>>(VPIN&15))&1)
|
||||||
|
|
||||||
#define NOP(x) for(unsigned _nopcount = x; _nopcount; _nopcount--) { asm("NOP"); }
|
#define NOP(x) for(unsigned _nopcount = x; _nopcount; _nopcount--) { asm("NOP"); }
|
||||||
|
@ -231,7 +248,8 @@ enum SCSI_DEVICE_TYPE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Parity bit generation
|
// Parity bit generation
|
||||||
#define PTY(V) (1^((V)^((V)>>1)^((V)>>2)^((V)>>3)^((V)>>4)^((V)>>5)^((V)>>6)^((V)>>7))&1)
|
//#define PTY(V) (1^((V)^((V)>>1)^((V)>>2)^((V)>>3)^((V)>>4)^((V)>>5)^((V)>>6)^((V)>>7))&1)
|
||||||
|
#define PTY(n) ((1 ^ (n) ^ ((n)>>1) ^ ((n)>>2) ^ ((n)>>3) ^ ((n)>>4) ^ ((n)>>5) ^ ((n)>>6) ^ ((n)>>7)) & 1)
|
||||||
|
|
||||||
// Data byte to BSRR register setting value conversion table
|
// Data byte to BSRR register setting value conversion table
|
||||||
// BSRR[31:24] = DB[7:0]
|
// BSRR[31:24] = DB[7:0]
|
||||||
|
@ -263,7 +281,7 @@ uint32_t db_bsrr[256];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct SCSI_INQUIRY_DATA
|
typedef struct _SCSI_INQUIRY_DATA
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
@ -306,23 +324,22 @@ struct SCSI_INQUIRY_DATA
|
||||||
// raw bytes
|
// raw bytes
|
||||||
byte raw[64];
|
byte raw[64];
|
||||||
};
|
};
|
||||||
};
|
} SCSI_INQUIRY_DATA;
|
||||||
|
|
||||||
// HDD image
|
// HDD image
|
||||||
typedef __attribute__((aligned(4))) struct _SCSI_DEVICE
|
typedef __attribute__((aligned(4))) struct _SCSI_DEVICE
|
||||||
{
|
{
|
||||||
FsFile *m_file; // File object
|
FsFile m_file; // File object
|
||||||
uint64_t m_fileSize; // File size
|
uint64_t m_fileSize; // File size
|
||||||
uint16_t m_blocksize; // SCSI BLOCK size
|
uint16_t m_blocksize; // SCSI BLOCK size
|
||||||
uint16_t m_rawblocksize; // OPTICAL raw sector size
|
uint16_t m_rawblocksize; // OPTICAL raw sector size
|
||||||
uint8_t m_type; // SCSI device type
|
uint8_t m_type; // SCSI device type
|
||||||
uint32_t m_blockcount; // blockcount
|
uint32_t m_blockcount; // blockcount
|
||||||
bool m_raw; // Raw disk
|
SCSI_INQUIRY_DATA inquiry_block; // SCSI information
|
||||||
SCSI_INQUIRY_DATA *inquiry_block; // SCSI information
|
|
||||||
uint8_t m_senseKey; // Sense key
|
uint8_t m_senseKey; // Sense key
|
||||||
uint16_t m_additional_sense_code; // ASC/ASCQ
|
uint16_t m_additional_sense_code; // ASC/ASCQ
|
||||||
bool m_mode2; // MODE2 CDROM
|
|
||||||
uint8_t m_sector_offset; // optical sector offset for missing sync header
|
uint8_t m_sector_offset; // optical sector offset for missing sync header
|
||||||
|
uint8_t flags; // various device flags
|
||||||
} SCSI_DEVICE;
|
} SCSI_DEVICE;
|
||||||
|
|
||||||
static byte cdb_len_lookup[] = {
|
static byte cdb_len_lookup[] = {
|
||||||
|
|
Loading…
Reference in New Issue