Skip to content

Commit

Permalink
More tape command implementations: Erase, Seek and ReadPosition
Browse files Browse the repository at this point in the history
  • Loading branch information
PetteriAimonen authored and erichelgeson committed May 26, 2023
1 parent fe4f94e commit a75508c
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/BlueSCSI_log_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ static const char *getCommandName(uint8_t cmd)
switch (cmd)
{
case 0x00: return "TestUnitReady";
case 0x01: return "RezeroUnit";
case 0x01: return "RezeroUnit/Rewind";
case 0x03: return "RequestSense";
case 0x04: return "FormatUnit";
case 0x05: return "ReadBlockLimits";
Expand All @@ -35,6 +35,7 @@ static const char *getCommandName(uint8_t cmd)
case 0x15: return "ModeSelect6";
case 0x16: return "Reserve";
case 0x17: return "Release";
case 0x19: return "Erase";
case 0x1A: return "ModeSense";
case 0x1B: return "StartStopUnit";
case 0x1C: return "ReceiveDiagnostic";
Expand All @@ -47,7 +48,7 @@ static const char *getCommandName(uint8_t cmd)
case 0x2C: return "Erase10";
case 0x2E: return "WriteVerify";
case 0x2F: return "Verify";
case 0x34: return "PreFetch";
case 0x34: return "PreFetch/ReadPosition";
case 0x35: return "SynchronizeCache";
case 0x36: return "LockUnlockCache";
case 0x37: return "ReadDefectData";
Expand Down
72 changes: 72 additions & 0 deletions src/BlueSCSI_tape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,31 @@ extern "C" {
#include <scsi.h>
}

static void doSeek(uint32_t lba)
{
image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
uint32_t capacity = img.file.size() / bytesPerSector;

debuglog("------ Locate tape to LBA ", (int)lba);

if (lba >= capacity)
{
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
scsiDev.phase = STATUS;
}
else
{
delay(10);
img.tape_pos = lba;

scsiDev.status = GOOD;
scsiDev.phase = STATUS;
}
}

extern "C" int scsiTapeCommand()
{
image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
Expand Down Expand Up @@ -158,6 +183,12 @@ extern "C" int scsiTapeCommand()
img.tape_pos += length;
}
}
else if (command == 0x19)
{
// Erase
// Just a stub implementation, fake erase to end of tape
img.tape_pos = img.scsiSectors;
}
else if (command == 0x01)
{
// REWIND
Expand Down Expand Up @@ -230,6 +261,47 @@ extern "C" int scsiTapeCommand()
scsiDev.phase = STATUS;
}
}
else if (command == 0x2B)
{
// Seek/Locate 10
uint32_t lba =
(((uint32_t) scsiDev.cdb[3]) << 24) +
(((uint32_t) scsiDev.cdb[4]) << 16) +
(((uint32_t) scsiDev.cdb[5]) << 8) +
scsiDev.cdb[6];

doSeek(lba);
}
else if (command == 0x34)
{
// ReadPosition
uint32_t lba = img.tape_pos;
scsiDev.data[0] = 0x00;
if (lba == 0) scsiDev.data[0] |= 0x80;
if (lba >= img.scsiSectors) scsiDev.data[0] |= 0x40;
scsiDev.data[1] = 0x00;
scsiDev.data[2] = 0x00;
scsiDev.data[3] = 0x00;
scsiDev.data[4] = (lba >> 24) & 0xFF; // Next block on tape
scsiDev.data[5] = (lba >> 16) & 0xFF;
scsiDev.data[6] = (lba >> 8) & 0xFF;
scsiDev.data[7] = (lba >> 0) & 0xFF;
scsiDev.data[8] = (lba >> 24) & 0xFF; // Last block in buffer
scsiDev.data[9] = (lba >> 16) & 0xFF;
scsiDev.data[10] = (lba >> 8) & 0xFF;
scsiDev.data[11] = (lba >> 0) & 0xFF;
scsiDev.data[12] = 0x00;
scsiDev.data[13] = 0x00;
scsiDev.data[14] = 0x00;
scsiDev.data[15] = 0x00;
scsiDev.data[16] = 0x00;
scsiDev.data[17] = 0x00;
scsiDev.data[18] = 0x00;
scsiDev.data[19] = 0x00;

scsiDev.phase = DATA_IN;
scsiDev.dataLen = 20;
}
else
{
commandHandled = 0;
Expand Down

0 comments on commit a75508c

Please sign in to comment.