scsi: Add illegal_command method.

- scsicdrom now logs unsupported commands instead of abort.
This commit is contained in:
joevt 2024-03-09 21:44:12 -08:00 committed by dingusdev
parent de8388f9a7
commit 3f826b8971
4 changed files with 125 additions and 10 deletions

View File

@ -189,6 +189,7 @@ public:
virtual int send_data(uint8_t* dst_ptr, int count);
virtual int rcv_data(const uint8_t* src_ptr, const int count);
virtual bool check_lun();
void illegal_command(const uint8_t* cmd);
virtual bool prepare_data() = 0;
virtual bool get_more_data() = 0;

View File

@ -56,44 +56,105 @@ void ScsiCdrom::process_command()
// use internal data buffer by default
this->data_ptr = this->data_buf;
switch (cmd_buf[0]) {
uint8_t* cmd = this->cmd_buf;
switch (cmd[0]) {
case ScsiCommand::TEST_UNIT_READY:
this->switch_phase(ScsiPhase::STATUS);
break;
case ScsiCommand::REWIND:
this->illegal_command(cmd);
break;
case ScsiCommand::REQ_SENSE:
this->illegal_command(cmd);
break;
case ScsiCommand::FORMAT_UNIT:
this->illegal_command(cmd);
break;
case ScsiCommand::READ_BLK_LIMITS:
this->illegal_command(cmd);
break;
case ScsiCommand::READ_6:
lba = ((cmd_buf[1] & 0x1F) << 16) + (cmd_buf[2] << 8) + cmd_buf[3];
this->read(lba, cmd_buf[4], 6);
lba = ((cmd[1] & 0x1F) << 16) + (cmd[2] << 8) + cmd[3];
this->read(lba, cmd[4], 6);
break;
case ScsiCommand::WRITE_6:
this->illegal_command(cmd);
break;
case ScsiCommand::SEEK_6:
this->illegal_command(cmd);
break;
case ScsiCommand::INQUIRY:
this->inquiry();
break;
case ScsiCommand::VERIFY_6:
this->illegal_command(cmd);
break;
case ScsiCommand::MODE_SELECT_6:
this->incoming_size = this->cmd_buf[4];
this->incoming_size = cmd[4];
this->switch_phase(ScsiPhase::DATA_OUT);
break;
case ScsiCommand::RELEASE_UNIT:
this->illegal_command(cmd);
break;
case ScsiCommand::ERASE_6:
this->illegal_command(cmd);
break;
case ScsiCommand::MODE_SENSE_6:
this->mode_sense();
break;
case ScsiCommand::START_STOP_UNIT:
this->illegal_command(cmd);
break;
case ScsiCommand::DIAG_RESULTS:
this->illegal_command(cmd);
break;
case ScsiCommand::SEND_DIAGS:
this->illegal_command(cmd);
break;
case ScsiCommand::PREVENT_ALLOW_MEDIUM_REMOVAL:
this->eject_allowed = (this->cmd_buf[4] & 1) == 0;
this->eject_allowed = (cmd[4] & 1) == 0;
this->switch_phase(ScsiPhase::STATUS);
break;
case ScsiCommand::READ_CAPACITY_10:
this->read_capacity();
break;
case ScsiCommand::READ_10:
lba = READ_DWORD_BE_U(&this->cmd_buf[2]);
xfer_len = READ_WORD_BE_U(&this->cmd_buf[7]);
if (this->cmd_buf[1] & 1) {
lba = READ_DWORD_BE_U(&cmd[2]);
xfer_len = READ_WORD_BE_U(&cmd[7]);
if (cmd[1] & 1) {
ABORT_F("%s: RelAdr bit set in READ_10", this->name.c_str());
}
read(lba, xfer_len, 10);
break;
case ScsiCommand::WRITE_10:
this->illegal_command(cmd);
break;
case ScsiCommand::VERIFY_10:
this->illegal_command(cmd);
break;
case ScsiCommand::READ_LONG_10:
this->illegal_command(cmd);
break;
case ScsiCommand::MODE_SENSE_10:
this->illegal_command(cmd);
break;
case ScsiCommand::READ_12:
this->illegal_command(cmd);
break;
// CD-ROM specific commands
case ScsiCommand::READ_TOC:
this->read_toc();
break;
case ScsiCommand::SET_CD_SPEED:
this->illegal_command(cmd);
break;
case ScsiCommand::READ_CD:
this->illegal_command(cmd);
break;
default:
ABORT_F("%s: unsupported command %d", this->name.c_str(), this->cmd_buf[0]);
this->illegal_command(cmd);
}
}

View File

@ -236,3 +236,15 @@ bool ScsiDevice::check_lun()
}
return true;
}
void ScsiDevice::illegal_command(const uint8_t *cmd)
{
LOG_F(ERROR, "%s: unsupported command: 0x%02x", this->name.c_str(), cmd[0]);
this->status = ScsiStatus::CHECK_CONDITION;
this->sense = ScsiSense::ILLEGAL_REQ;
this->asc = 0x20; // Invalid command operation code
this->ascq = 0;
this->sksv = 0xc0; // sksv=1, C/D=Command, BPV=0, BP=0
this->field = 0;
this->switch_phase(ScsiPhase::STATUS);
}

View File

@ -87,6 +87,9 @@ void ScsiHardDisk::process_command() {
case ScsiCommand::INQUIRY:
this->inquiry();
break;
case ScsiCommand::READ_BLK_LIMITS:
this->illegal_command(cmd);
break;
case ScsiCommand::READ_6:
lba = ((cmd[1] & 0x1F) << 16) + (cmd[2] << 8) + cmd[3];
transfer_len = cmd[4];
@ -112,20 +115,58 @@ void ScsiHardDisk::process_command() {
lba = ((cmd[1] & 0x1F) << 16) + (cmd[2] << 8) + cmd[3];
seek(lba);
break;
case ScsiCommand::VERIFY_6:
this->illegal_command(cmd);
break;
case ScsiCommand::MODE_SELECT_6:
mode_select_6(cmd[4]);
break;
case ScsiCommand::RELEASE_UNIT:
this->illegal_command(cmd);
break;
case ScsiCommand::ERASE_6:
this->illegal_command(cmd);
break;
case ScsiCommand::MODE_SENSE_6:
this->mode_sense_6();
break;
case ScsiCommand::START_STOP_UNIT:
this->illegal_command(cmd);
break;
case ScsiCommand::DIAG_RESULTS:
this->illegal_command(cmd);
break;
case ScsiCommand::SEND_DIAGS:
this->illegal_command(cmd);
break;
case ScsiCommand::READ_CAPACITY_10:
this->read_capacity_10();
break;
case ScsiCommand::VERIFY_10:
this->illegal_command(cmd);
break;
case ScsiCommand::READ_BUFFER:
read_buffer();
break;
case ScsiCommand::MODE_SENSE_10:
this->illegal_command(cmd);
break;
case ScsiCommand::READ_12:
this->illegal_command(cmd);
break;
// CD-ROM specific commands
case ScsiCommand::READ_TOC:
this->illegal_command(cmd);
break;
case ScsiCommand::SET_CD_SPEED:
this->illegal_command(cmd);
break;
case ScsiCommand::READ_CD:
this->illegal_command(cmd);
break;
default:
LOG_F(WARNING, "%s: unrecognized command: %x", this->name.c_str(), cmd[0]);
this->illegal_command(cmd);
}
}