mirror of
https://github.com/fhgwright/SCSI2SD.git
synced 2025-02-05 08:31:08 +00:00
Adding Ensoniq ASR-10 support and improved FORMAT UNIT command.
- Read the data-phase bytes during a FORMAT UNIT command - Return the exact number of bytes requested for the REQUEST SENSE command
This commit is contained in:
parent
3762d59973
commit
767f12e481
@ -1,5 +1,7 @@
|
||||
201404?? 3.4
|
||||
- Fix to ensure SCSI phase bits are set atomically.
|
||||
- Always return the requested number of bytes for a REQUEST SENSE command
|
||||
This is required to support the Ensoniq ASR-10.
|
||||
- Decreased (unused) heap and stack sizes to prepare for a memory
|
||||
write cache
|
||||
|
||||
|
@ -66,5 +66,5 @@ Users have reported success on these systems:
|
||||
Roland JS-30 Sampler
|
||||
Akai S1000, S3200, S3000XL, MPC 2000XL, DPS 12
|
||||
EMU Emulator E4X with EOS 3.00b and E6400 (classic) with Eos 4.01
|
||||
Ensoniq ASR-X
|
||||
Ensoniq ASR-X, ASR-10 (from v3.4, 2GB size limit)
|
||||
HP 16601A logic analyzer
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "device.h"
|
||||
#include "scsi.h"
|
||||
#include "scsiPhy.h"
|
||||
#include "config.h"
|
||||
#include "disk.h"
|
||||
#include "sd.h"
|
||||
@ -38,11 +39,69 @@ static int doSdInit()
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void doFormatUnit()
|
||||
// Callback once all data has been read in the data out phase.
|
||||
static void doFormatUnitComplete(void)
|
||||
{
|
||||
// Low-level formatting is not required.
|
||||
// Nothing left to do.
|
||||
// TODO start writing the initialisation pattern to the SD
|
||||
// card
|
||||
scsiDev.phase = STATUS;
|
||||
}
|
||||
|
||||
static void doFormatUnitSkipData(int bytes)
|
||||
{
|
||||
// We may not have enough memory to store the initialisation pattern and
|
||||
// defect list data. Since we're not making use of it yet anyway, just
|
||||
// discard the bytes.
|
||||
scsiEnterPhase(DATA_OUT);
|
||||
int i;
|
||||
for (i = 0; i < bytes; ++i)
|
||||
{
|
||||
scsiReadByte();
|
||||
}
|
||||
}
|
||||
|
||||
// Callback from the data out phase.
|
||||
static void doFormatUnitPatternHeader(void)
|
||||
{
|
||||
int defectLength =
|
||||
((((uint16_t)scsiDev.data[2])) << 8) +
|
||||
scsiDev.data[3];
|
||||
|
||||
int patternLength =
|
||||
((((uint16_t)scsiDev.data[4 + 2])) << 8) +
|
||||
scsiDev.data[4 + 3];
|
||||
|
||||
doFormatUnitSkipData(defectLength + patternLength);
|
||||
doFormatUnitComplete();
|
||||
}
|
||||
|
||||
// Callback from the data out phase.
|
||||
static void doFormatUnitHeader(void)
|
||||
{
|
||||
int IP = (scsiDev.data[1] & 0x08) ? 1 : 0;
|
||||
int DSP = (scsiDev.data[1] & 0x04) ? 1 : 0;
|
||||
|
||||
if (! DSP) // disable save parameters
|
||||
{
|
||||
configSave(); // Save the "MODE SELECT savable parameters"
|
||||
}
|
||||
|
||||
if (IP)
|
||||
{
|
||||
// We need to read the initialisation pattern header first.
|
||||
scsiDev.dataLen += 4;
|
||||
scsiDev.phase = DATA_OUT;
|
||||
scsiDev.postDataOutHook = doFormatUnitPatternHeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read the defect list data
|
||||
int defectLength =
|
||||
((((uint16_t)scsiDev.data[2])) << 8) +
|
||||
scsiDev.data[3];
|
||||
doFormatUnitSkipData(defectLength);
|
||||
doFormatUnitComplete();
|
||||
}
|
||||
}
|
||||
|
||||
static void doReadCapacity()
|
||||
@ -240,7 +299,22 @@ int scsiDiskCommand()
|
||||
else if (command == 0x04)
|
||||
{
|
||||
// FORMAT UNIT
|
||||
doFormatUnit();
|
||||
// We don't really do any formatting, but we need to read the correct
|
||||
// number of bytes in the DATA_OUT phase to make the SCSI host happy.
|
||||
|
||||
int fmtData = (scsiDev.cdb[1] & 0x10) ? 1 : 0;
|
||||
if (fmtData)
|
||||
{
|
||||
// We need to read the parameter list, but we don't know how
|
||||
// big it is yet. Start with the header.
|
||||
scsiDev.dataLen = 4;
|
||||
scsiDev.phase = DATA_OUT;
|
||||
scsiDev.postDataOutHook = doFormatUnitHeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No data to read, we're already finished!
|
||||
}
|
||||
}
|
||||
else if (command == 0x08)
|
||||
{
|
||||
|
@ -281,8 +281,12 @@ static void process_Command()
|
||||
{
|
||||
// REQUEST SENSE
|
||||
uint32 allocLength = scsiDev.cdb[4];
|
||||
if (allocLength == 0) allocLength = 256;
|
||||
memset(scsiDev.data, 0, 18);
|
||||
|
||||
// As specified by the SASI and SCSI1 standard.
|
||||
// Newer initiators won't be specifying 0 anyway.
|
||||
if (allocLength == 0) allocLength = 4;
|
||||
|
||||
memset(scsiDev.data, 0, 256); // Max possible alloc length
|
||||
scsiDev.data[0] = 0xF0;
|
||||
scsiDev.data[2] = scsiDev.sense.code & 0x0F;
|
||||
|
||||
@ -292,23 +296,12 @@ static void process_Command()
|
||||
scsiDev.data[6] = transfer.lba;
|
||||
|
||||
// Additional bytes if there are errors to report
|
||||
int responseLength;
|
||||
if (scsiDev.sense.code == NO_SENSE)
|
||||
{
|
||||
responseLength = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseLength = 18;
|
||||
scsiDev.data[7] = 10; // additional length
|
||||
scsiDev.data[12] = scsiDev.sense.asc >> 8;
|
||||
scsiDev.data[13] = scsiDev.sense.asc;
|
||||
}
|
||||
scsiDev.data[7] = 10; // additional length
|
||||
scsiDev.data[12] = scsiDev.sense.asc >> 8;
|
||||
scsiDev.data[13] = scsiDev.sense.asc;
|
||||
|
||||
// Silently truncate results. SCSI-2 spec 8.2.14.
|
||||
enter_DataIn(
|
||||
(allocLength < responseLength) ? allocLength : responseLength
|
||||
);
|
||||
enter_DataIn(allocLength);
|
||||
|
||||
// This is a good time to clear out old sense information.
|
||||
scsiDev.sense.code = NO_SENSE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user