Skip to content

Commit

Permalink
Add more tape drive command implementations
Browse files Browse the repository at this point in the history
- Write
- ReadBlockLimits
- WriteFilemarks (dummy result)
- Verify (dummy result)
  • Loading branch information
PetteriAimonen authored and erichelgeson committed May 14, 2023
1 parent cc3587d commit ea15cd2
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/BlueSCSI_log_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ static const char *getCommandName(uint8_t cmd)
case 0x01: return "RezeroUnit";
case 0x03: return "RequestSense";
case 0x04: return "FormatUnit";
case 0x05: return "ReadBlockLimits";
case 0x08: return "Read6";
case 0x0A: return "Write6";
case 0x0B: return "Seek6";
case 0x0F: return "WriteSectorBuffer";
case 0x10: return "WriteFilemarks";
case 0x11: return "Space";
case 0x12: return "Inquiry";
case 0x13: return "Verify";
case 0x15: return "ModeSelect6";
case 0x16: return "Reserve";
case 0x17: return "Release";
Expand Down
99 changes: 98 additions & 1 deletion src/BlueSCSI_tape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ extern "C" int scsiTapeCommand()
bool overlength = (length < blocklen);
if (overlength || (underlength && !supress_invalid_length))
{
debuglog("Host requested variable block max ", (int)length, " bytes, blocksize is ", (int)blocklen);
debuglog("------ Host requested variable block max ", (int)length, " bytes, blocksize is ", (int)blocklen);
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
Expand All @@ -81,12 +81,109 @@ extern "C" int scsiTapeCommand()
img.tape_pos += blocks_to_read;
}
}
else if (command == 0x0A)
{
// WRITE6
bool fixed = scsiDev.cdb[1] & 1;

if (img.quirks == S2S_CFG_QUIRKS_OMTI)
{
fixed = true;
}

uint32_t length =
(((uint32_t) scsiDev.cdb[2]) << 16) +
(((uint32_t) scsiDev.cdb[3]) << 8) +
scsiDev.cdb[4];

// Host can request either multiple fixed-length blocks, or a single variable length one.
// Only single block length is supported currently.
uint32_t blocklen = scsiDev.target->liveCfg.bytesPerSector;
uint32_t blocks_to_write = length;
if (!fixed)
{
blocks_to_write = 1;

if (length != blocklen)
{
debuglog("------ Host requested variable block ", (int)length, " bytes, blocksize is ", (int)blocklen);
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
scsiDev.phase = STATUS;
return 1;
}
}

if (blocks_to_write > 0)
{
scsiDiskStartWrite(img.tape_pos, blocks_to_write);
img.tape_pos += blocks_to_write;
}
}
else if (command == 0x13)
{
// VERIFY
bool fixed = scsiDev.cdb[1] & 1;

if (img.quirks == S2S_CFG_QUIRKS_OMTI)
{
fixed = true;
}

bool byte_compare = scsiDev.cdb[1] & 2;
uint32_t length =
(((uint32_t) scsiDev.cdb[2]) << 16) +
(((uint32_t) scsiDev.cdb[3]) << 8) +
scsiDev.cdb[4];

if (!fixed)
{
length = 1;
}

if (byte_compare)
{
debuglog("------ Verify with byte compare is not implemented");
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
scsiDev.phase = STATUS;
}
else
{
// Host requests ECC check, report that it passed.
scsiDev.status = GOOD;
scsiDev.phase = STATUS;
img.tape_pos += length;
}
}
else if (command == 0x01)
{
// REWIND
// Set tape position back to 0.
img.tape_pos = 0;
}
else if (command == 0x05)
{
// READ BLOCK LIMITS
uint32_t blocklen = scsiDev.target->liveCfg.bytesPerSector;
scsiDev.data[0] = 0; // Reserved
scsiDev.data[1] = (blocklen >> 16) & 0xFF; // Maximum block length (MSB)
scsiDev.data[2] = (blocklen >> 8) & 0xFF;
scsiDev.data[3] = (blocklen >> 0) & 0xFF; // Maximum block length (LSB)
scsiDev.data[4] = (blocklen >> 8) & 0xFF; // Minimum block length (MSB)
scsiDev.data[5] = (blocklen >> 8) & 0xFF; // Minimum block length (MSB)
scsiDev.dataLen = 6;
scsiDev.phase = DATA_IN;
}
else if (command == 0x10)
{
// WRITE FILEMARKS
debuglog("------ Filemarks storage not implemented, reporting ok");
scsiDev.status = GOOD;
scsiDev.phase = STATUS;
}
else if (command == 0x11)
{
// SPACE
Expand Down

0 comments on commit ea15cd2

Please sign in to comment.