mirror of
https://github.com/dkgrizzly/GreenSCSI.git
synced 2025-01-22 10:30:19 +00:00
524 lines
17 KiB
C++
Executable File
524 lines
17 KiB
C++
Executable File
#include "config.h"
|
|
#include "scsi_defs.h"
|
|
|
|
|
|
/*
|
|
* INQUIRY command processing.
|
|
*/
|
|
void InquiryCommandHandler() {
|
|
LOGN("[Inquiry]");
|
|
uint8_t len;
|
|
|
|
if(!m_sel) {
|
|
memset(m_responsebuffer, 0, 96);
|
|
m_responsebuffer[0] = 0x7f;
|
|
m_responsebuffer[4] = 35 - 4;
|
|
len = 36;
|
|
} else {
|
|
memcpy(m_responsebuffer, m_sel->m_inquiryresponse, 96);
|
|
len = m_responsebuffer[4] + 5;
|
|
}
|
|
|
|
len = min(len, m_cmd[4]);
|
|
writeDataPhase(len, m_responsebuffer);
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
/*
|
|
* REQUEST SENSE command processing.
|
|
*/
|
|
void RequestSenseCommandHandler() {
|
|
LOGN("[RequestSense]");
|
|
uint8_t len = m_cmd[4];
|
|
uint8_t buf[18] = {
|
|
0x70, //CheckCondition
|
|
0, //Segment number
|
|
0x00, //Sense key
|
|
0, 0, 0, 0, //information
|
|
17 - 7 , //Additional data length
|
|
0,
|
|
};
|
|
|
|
if(!m_sel) {
|
|
buf[2] = 2; // Not ready
|
|
buf[12] = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
|
buf[13] = 0x03;
|
|
} else {
|
|
buf[2] = m_sel->m_sense.m_key;
|
|
buf[12] = m_sel->m_sense.m_code;
|
|
buf[13] = m_sel->m_sense.m_key_specific[0];
|
|
buf[14] = m_sel->m_sense.m_key_specific[1];
|
|
buf[15] = m_sel->m_sense.m_key_specific[2];
|
|
|
|
m_sel->m_sense.m_key = 0;
|
|
m_sel->m_sense.m_code = 0;
|
|
m_sel->m_sense.m_key_specific[0] = 0;
|
|
m_sel->m_sense.m_key_specific[1] = 0;
|
|
m_sel->m_sense.m_key_specific[2] = 0;
|
|
}
|
|
|
|
writeDataPhase(len < 18 ? len : 18, buf);
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void TestUnitCommandHandler() {
|
|
LOGN("[TestUnit]");
|
|
if(!m_sel) {
|
|
m_sts |= STATUS_CHECK;
|
|
return;
|
|
}
|
|
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
|
m_sts |= STATUS_CHECK;
|
|
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
|
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
|
m_sel->m_sense.m_key_specific[0] = 0x03;
|
|
return;
|
|
}
|
|
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void RezeroUnitCommandHandler() {
|
|
LOGN("[RezeroUnit]");
|
|
if(!m_sel) {
|
|
m_sts |= STATUS_CHECK;
|
|
return;
|
|
}
|
|
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
|
m_sts |= STATUS_CHECK;
|
|
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
|
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
|
m_sel->m_sense.m_key_specific[0] = 0x03;
|
|
return;
|
|
}
|
|
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void FormatUnitCommandHandler() {
|
|
LOGN("[FormatUnit]");
|
|
if(!m_sel) {
|
|
m_sts |= STATUS_CHECK;
|
|
return;
|
|
}
|
|
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
|
m_sts |= STATUS_CHECK;
|
|
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
|
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
|
m_sel->m_sense.m_key_specific[0] = 0x03;
|
|
return;
|
|
}
|
|
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void ReassignBlocksCommandHandler() {
|
|
LOGN("[ReassignBlocks]");
|
|
if(!m_sel) {
|
|
m_sts |= STATUS_CHECK;
|
|
return;
|
|
}
|
|
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
|
m_sts |= STATUS_CHECK;
|
|
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
|
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
|
m_sel->m_sense.m_key_specific[0] = 0x03;
|
|
return;
|
|
}
|
|
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
#if SUPPORT_APPLE
|
|
void AppleEECommandHandler() {
|
|
LOGN("[Apple:0xEE]");
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* MODE SENSE command processing.
|
|
*/
|
|
void ModeSenseCommandHandler()
|
|
{
|
|
uint16_t len, maxlen;
|
|
int page, pagemax, pagemin;
|
|
|
|
switch(m_cmd[0]) {
|
|
case CMD_MODE_SENSE6:
|
|
LOGN("[ModeSense6]");
|
|
maxlen = m_cmd[4];
|
|
len = 1;
|
|
break;
|
|
case CMD_MODE_SENSE10:
|
|
LOGN("[ModeSense10]");
|
|
maxlen = ((uint16_t)m_cmd[7] << 8) | m_cmd[8];
|
|
len = 2;
|
|
break;
|
|
default:
|
|
m_sts |= STATUS_CHECK;
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
|
|
/* Check whether medium is present */
|
|
if(!m_sel) {
|
|
m_sts |= STATUS_CHECK; // Image file absent
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
if(!m_sel->m_rawPart && !m_sel->m_file.isOpen()) {
|
|
m_sts |= STATUS_CHECK;
|
|
m_sel->m_sense.m_key = NOT_READY; // Not ready
|
|
m_sel->m_sense.m_code = LUN_NOT_READY; // Logical Unit Not Ready, Manual Intervention Required
|
|
m_sel->m_sense.m_key_specific[0] = 0x03;
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
|
|
memset(m_responsebuffer, 0, sizeof(m_responsebuffer));
|
|
|
|
{
|
|
/* Default medium type */
|
|
m_responsebuffer[len++] = (m_sel->m_type == DEV_OPTICAL) ? 0xf0 : 0x00;
|
|
/* Write protected */
|
|
m_responsebuffer[len++] = (m_sel->m_type == DEV_OPTICAL) ? 0x80 : 0x00;
|
|
|
|
// ModeSense10 has two extra bytes, and Block Descriptor Length has an extra MSB
|
|
if(m_cmd[0] == CMD_MODE_SENSE10) {
|
|
len += 2;
|
|
m_responsebuffer[len++] = 0;
|
|
}
|
|
|
|
/* Add block descriptor if DBD is not set */
|
|
if (m_cmd[1] & 0x08) {
|
|
m_responsebuffer[len++] = 0; /* No block descriptor */
|
|
} else {
|
|
if(m_sel->m_type == DEV_TAPE) {
|
|
m_responsebuffer[len++] = 8; /* Block descriptor length */
|
|
m_responsebuffer[len++] = 0x40; /* Medium Density Code */
|
|
m_responsebuffer[len++] = 0x00; /* Number of Blocks (0) */
|
|
m_responsebuffer[len++] = 0x00;
|
|
m_responsebuffer[len++] = 0x00;
|
|
m_responsebuffer[len++] = 0x00; /* Block Length 1024 */
|
|
m_responsebuffer[len++] = 0x00;
|
|
m_responsebuffer[len++] = 0x04;
|
|
m_responsebuffer[len++] = 0x00;
|
|
} else {
|
|
uint32_t capacity = (m_sel->m_fileSize / m_sel->m_blocksize) - 1;
|
|
m_responsebuffer[len++] = 8; /* Block descriptor length */
|
|
m_responsebuffer[len++] = (capacity >> 24) & 0xff;
|
|
m_responsebuffer[len++] = (capacity >> 16) & 0xff;
|
|
m_responsebuffer[len++] = (capacity >> 8) & 0xff;
|
|
m_responsebuffer[len++] = capacity & 0xff;
|
|
m_responsebuffer[len++] = (m_sel->m_blocksize >> 24) & 0xff;
|
|
m_responsebuffer[len++] = (m_sel->m_blocksize >> 16) & 0xff;
|
|
m_responsebuffer[len++] = (m_sel->m_blocksize >> 8) & 0xff;
|
|
m_responsebuffer[len++] = (m_sel->m_blocksize) & 0xff;
|
|
}
|
|
}
|
|
|
|
/* Check for requested mode page */
|
|
page = m_cmd[2] & 0x3F;
|
|
pagemax = (page != 0x3f) ? page : 0x3e;
|
|
pagemin = (page != 0x3f) ? page : 0x00;
|
|
for(page = pagemax; page >= pagemin; page--) {
|
|
switch (page) {
|
|
case MODEPAGE_VENDOR_SPECIFIC:
|
|
/* Accept request only for current values */
|
|
if (m_cmd[2] & 0xC0) {
|
|
//DEBUGPRINT(DBG_TRACE, " [2]==%d", m_cmd[2]);
|
|
/* Prepare sense data */
|
|
m_sts |= STATUS_CHECK;
|
|
m_sel->m_sense.m_key = ILLEGAL_REQUEST;
|
|
m_sel->m_sense.m_code = INVALID_FIELD_IN_CDB; /* "Invalid field in CDB" */
|
|
m_sel->m_sense.m_key_specific[0] = ERROR_IN_OPCODE; /* "Error in Byte 2" */
|
|
m_sel->m_sense.m_key_specific[1] = 0x00;
|
|
m_sel->m_sense.m_key_specific[2] = 0x02;
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
|
|
/* Unit attention */
|
|
m_responsebuffer[len++] = 0x80; // PS, page id
|
|
m_responsebuffer[len++] = 0x02; // Page length
|
|
m_responsebuffer[len++] = 0x00;
|
|
m_responsebuffer[len++] = 0x00;
|
|
break;
|
|
case MODEPAGE_RW_ERROR_RECOVERY:
|
|
if(m_cmd[2] & 0x40) {
|
|
m_sts |= STATUS_CHECK;
|
|
m_sel->m_sense.m_key = ILLEGAL_REQUEST;
|
|
m_sel->m_sense.m_code = INVALID_FIELD_IN_CDB; /* "Invalid field in CDB" */
|
|
m_sel->m_sense.m_key_specific[0] = ERROR_IN_OPCODE; /* "Error in Byte 2" */
|
|
m_sel->m_sense.m_key_specific[1] = 0x00;
|
|
m_sel->m_sense.m_key_specific[2] = 0x02;
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
m_responsebuffer[len++] = MODEPAGE_RW_ERROR_RECOVERY; // PS, page id
|
|
m_responsebuffer[len++] = 0x0a; // Page length
|
|
m_responsebuffer[len++] = 0x05; //
|
|
m_responsebuffer[len++] = 0x00; // Read Retry Count
|
|
m_responsebuffer[len++] = 0x00; // Reserved
|
|
m_responsebuffer[len++] = 0x00; // Reserved
|
|
m_responsebuffer[len++] = 0x00; // Reserved
|
|
m_responsebuffer[len++] = 0x00; // Reserved
|
|
m_responsebuffer[len++] = 0x00; // Write Retry Count
|
|
m_responsebuffer[len++] = 0x00; // Reserved
|
|
m_responsebuffer[len++] = 0x00; // Recovery Time Limit
|
|
m_responsebuffer[len++] = 0x00;
|
|
break;
|
|
#if 0
|
|
case MODEPAGE_DCRC_PARAMETERS:
|
|
m_responsebuffer[len++] = 0x82; // PS, page id
|
|
m_responsebuffer[len++] = 0x0e; // Page length
|
|
m_responsebuffer[len++] = 0xe6; // Buffer full ratio, 90%
|
|
m_responsebuffer[len++] = 0x1a; // Buffer empty ratio, 10%
|
|
m_responsebuffer[len++] = 0x00; // Bus inactivity limit
|
|
m_responsebuffer[len++] = 0x00;
|
|
m_responsebuffer[len++] = 0x00; // Disconnect time limit
|
|
m_responsebuffer[len++] = 0x00;
|
|
m_responsebuffer[len++] = 0x00; // Connect time limit
|
|
m_responsebuffer[len++] = 0x00;
|
|
m_responsebuffer[len++] = 0x00; // Maximum burst size
|
|
m_responsebuffer[len++] = 0x00;
|
|
m_responsebuffer[len++] = 0x00; // EMDP, Dimm, DTDC
|
|
m_responsebuffer[len++] = 0x00; // Reserved
|
|
m_responsebuffer[len++] = 0x00; // Reserved
|
|
m_responsebuffer[len++] = 0x00; // Reserved
|
|
break;
|
|
#endif
|
|
#if SUPPORT_APPLE
|
|
case MODEPAGE_APPLE:
|
|
if( m_sel->m_quirks & QUIRKS_APPLE) {
|
|
m_responsebuffer[len++] = 0xb0;
|
|
m_responsebuffer[len++] = 0x16;
|
|
m_responsebuffer[len++] = 'A';
|
|
m_responsebuffer[len++] = 'P';
|
|
m_responsebuffer[len++] = 'P';
|
|
m_responsebuffer[len++] = 'L';
|
|
m_responsebuffer[len++] = 'E';
|
|
m_responsebuffer[len++] = ' ';
|
|
m_responsebuffer[len++] = 'C';
|
|
m_responsebuffer[len++] = 'O';
|
|
m_responsebuffer[len++] = 'M';
|
|
m_responsebuffer[len++] = 'P';
|
|
m_responsebuffer[len++] = 'U';
|
|
m_responsebuffer[len++] = 'T';
|
|
m_responsebuffer[len++] = 'E';
|
|
m_responsebuffer[len++] = 'R';
|
|
m_responsebuffer[len++] = ',';
|
|
m_responsebuffer[len++] = ' ';
|
|
m_responsebuffer[len++] = 'I';
|
|
m_responsebuffer[len++] = 'N';
|
|
m_responsebuffer[len++] = 'C';
|
|
m_responsebuffer[len++] = ' ';
|
|
m_responsebuffer[len++] = ' ';
|
|
m_responsebuffer[len++] = ' ';
|
|
}
|
|
break;
|
|
#endif
|
|
case MODEPAGE_FORMAT_PARAMETERS:
|
|
m_responsebuffer[len + 0] = MODEPAGE_FORMAT_PARAMETERS; //Page code
|
|
m_responsebuffer[len + 1] = 0x16; // Page length
|
|
if((m_cmd[2] >> 6) != 1) {
|
|
m_responsebuffer[len + 11] = 0x3F; // Number of sectors / track
|
|
m_responsebuffer[len + 12] = (m_sel->m_blocksize >> 8) & 0xff; // Blocksize MSB
|
|
m_responsebuffer[len + 13] = (m_sel->m_blocksize >> 0) & 0xff; // Blocksize LSB
|
|
m_responsebuffer[len + 15] = 0x1; // Interleave
|
|
}
|
|
len += 24;
|
|
break;
|
|
case MODEPAGE_RIGID_GEOMETRY:
|
|
m_responsebuffer[len + 0] = MODEPAGE_RIGID_GEOMETRY; //Page code
|
|
m_responsebuffer[len + 1] = 0x16; // Page length
|
|
if((m_cmd[2] >> 6) != 1) {
|
|
m_responsebuffer[len + 2] = m_sel->m_cylinders >> 16; // Number of cylinders
|
|
m_responsebuffer[len + 3] = m_sel->m_cylinders >> 8;
|
|
m_responsebuffer[len + 4] = m_sel->m_cylinders;
|
|
m_responsebuffer[len + 5] = m_sel->m_heads; // Number of heads
|
|
memcpy(&m_responsebuffer[len + 6], &m_responsebuffer[len + 2], 3); // Write Precomp Cyl
|
|
memcpy(&m_responsebuffer[len + 9], &m_responsebuffer[len + 2], 3); // Reduced Write Current Cyl
|
|
m_responsebuffer[len + 20] = 0x1C; // 7200 RPM
|
|
m_responsebuffer[len + 21] = 0x20;
|
|
}
|
|
len += 24;
|
|
break;
|
|
case MODEPAGE_FLEXIBLE_GEOMETRY:
|
|
{
|
|
m_responsebuffer[len + 0] = MODEPAGE_FLEXIBLE_GEOMETRY; //Page code
|
|
m_responsebuffer[len + 1] = 0x1E; // Page length
|
|
m_responsebuffer[len + 2] = 0x03; // Transfer rate 1mbit/s (MSB)
|
|
m_responsebuffer[len + 3] = 0xE8; // Transfer rate 1mbit/s (LSB)
|
|
m_responsebuffer[len + 4] = 16; // Number of heads
|
|
m_responsebuffer[len + 5] = 18; // Sectors per track
|
|
m_responsebuffer[len + 6] = 0x20; // Data bytes per sector (MSB)
|
|
m_responsebuffer[len + 6] = 0x00; // Data bytes per sector (LSB)
|
|
len += 24;
|
|
}
|
|
break;
|
|
default:
|
|
if(pagemin == pagemax) {
|
|
m_sts |= STATUS_CHECK;
|
|
m_sel->m_sense.m_key = ILLEGAL_REQUEST;
|
|
m_sel->m_sense.m_code = INVALID_FIELD_IN_CDB; /* "Invalid field in CDB" */
|
|
m_sel->m_sense.m_key_specific[0] = ERROR_IN_OPCODE; /* "Error in Byte 2" */
|
|
m_sel->m_sense.m_key_specific[1] = 0x00;
|
|
m_sel->m_sense.m_key_specific[2] = 0x02;
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Report size of requested data */
|
|
if(m_cmd[0] == CMD_MODE_SENSE6) {
|
|
m_responsebuffer[0] = len;
|
|
} else {
|
|
m_responsebuffer[0] = (len >> 8) & 0xff;
|
|
m_responsebuffer[1] = len & 0xff;
|
|
}
|
|
|
|
/* Truncate data if necessary */
|
|
if (maxlen < len) {
|
|
len = maxlen;
|
|
}
|
|
|
|
// Send it
|
|
writeDataPhase(len, m_responsebuffer);
|
|
}
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
uint8_t onModeSelectCommand() {
|
|
return STATUS_GOOD;
|
|
}
|
|
|
|
void ModeSelect6CommandHandler() {
|
|
LOG("[ModeSelect6] ");
|
|
uint16_t len = m_cmd[4];
|
|
if(!m_sel) {
|
|
m_sts |= STATUS_CHECK; // Image file absent
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
if(len > MAX_BLOCKSIZE) {
|
|
m_sel->m_sense.m_key = ILLEGAL_REQUEST;
|
|
m_sel->m_sense.m_code = INVALID_FIELD_IN_CDB; /* "Invalid field in CDB" */
|
|
m_sel->m_sense.m_key_specific[0] = ERROR_IN_OPCODE; /* "Error in Byte 4" */
|
|
m_sel->m_sense.m_key_specific[1] = 0x00;
|
|
m_sel->m_sense.m_key_specific[2] = 0x04;
|
|
m_sts |= STATUS_CHECK;
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
readDataPhase(len, m_responsebuffer);
|
|
|
|
for(int i = 1; i < len; i++ ) {
|
|
LOG(":");
|
|
LOGHEX2(m_responsebuffer[i]);
|
|
}
|
|
LOGN("");
|
|
m_sts |= onModeSelectCommand();
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void ModeSelect10CommandHandler() {
|
|
LOGN("[ModeSelect10]");
|
|
uint16_t len = ((uint16_t)m_cmd[7] << 8) | m_cmd[8];
|
|
if(!m_sel) {
|
|
m_sts |= STATUS_CHECK; // Image file absent
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
if(len > MAX_BLOCKSIZE) {
|
|
m_sel->m_sense.m_key = ILLEGAL_REQUEST;
|
|
m_sel->m_sense.m_code = INVALID_FIELD_IN_CDB; /* "Invalid field in CDB" */
|
|
m_sel->m_sense.m_key_specific[0] = ERROR_IN_OPCODE; /* "Error in Byte 7" */
|
|
m_sel->m_sense.m_key_specific[1] = 0x00;
|
|
m_sel->m_sense.m_key_specific[2] = 0x07;
|
|
m_sts |= STATUS_CHECK;
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
readDataPhase(len, m_responsebuffer);
|
|
|
|
for(int i = 1; i < len; i++ ) {
|
|
LOG(":");
|
|
LOGHEX2(m_responsebuffer[i]);
|
|
}
|
|
LOGN("");
|
|
m_sts |= onModeSelectCommand();
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void SearchDataEqualCommandHandler() {
|
|
LOGN("[SearchDataEqual]");
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void SendDiagnosticCommandHandler() {
|
|
LOGN("[SendDiagnostic]");
|
|
if(!m_sel) {
|
|
m_sts |= STATUS_CHECK; // Image file absent
|
|
m_phase = PHASE_STATUSIN;
|
|
return;
|
|
}
|
|
if(m_cmd[1] & 0x04) {
|
|
} else {
|
|
m_sel->m_sense.m_code = INVALID_FIELD_IN_CDB; /* "Invalid field in CDB" */
|
|
m_sel->m_sense.m_key_specific[0] = ERROR_IN_OPCODE; /* "Error in Byte 1" */
|
|
m_sel->m_sense.m_key_specific[1] = 0x00;
|
|
m_sel->m_sense.m_key_specific[2] = 0x01;
|
|
m_sts |= STATUS_CHECK;
|
|
}
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void ReadDefectCommandHandler() {
|
|
LOGN("[ReadDefect]");
|
|
m_responsebuffer[0] = 0x00;
|
|
m_responsebuffer[1] = m_cmd[2];
|
|
m_responsebuffer[2] = m_cmd[7]; // List Length MSB
|
|
m_responsebuffer[3] = m_cmd[8]; // List Length LSB
|
|
writeDataPhase(4, m_responsebuffer);
|
|
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void StartStopUnitCommandHandler() {
|
|
LOGN("[StartStopUnit]");
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void PreAllowMediumRemovalCommandHandler() {
|
|
LOGN("[PreAllowMed.Removal]");
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void PrefetchCommandHandler() {
|
|
LOGN("[Prefetch]");
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void SyncCacheCommandHandler() {
|
|
LOGN("[SyncCache]");
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void UnknownCommandHandler() {
|
|
LOGN("[*Unknown]");
|
|
m_sts |= STATUS_CHECK;
|
|
if(m_sel) {
|
|
m_sel->m_sense.m_key = 5;
|
|
}
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|
|
|
|
void BadLunCommandHandler() {
|
|
LOGN("[Bad LUN]");
|
|
m_sts |= STATUS_CHECK;
|
|
m_phase = PHASE_STATUSIN;
|
|
}
|