Buslogic specific features and commands marked as invalid when the Adaptec 154x scsi controller is selected.

Some SCSI layer bugfixes.
This commit is contained in:
TC1995
2017-01-03 19:07:18 +01:00
parent b44f86a625
commit abbd603d9a
4 changed files with 397 additions and 345 deletions

View File

@@ -1,10 +1,7 @@
/* Copyright holders: SA1988 /* Copyright holders: SA1988
see COPYING for more details see COPYING for more details
*/ */
/*Buslogic SCSI emulation (including Adaptec 154x ISA software backward compatibility)*/ /*Buslogic SCSI emulation (including Adaptec 154x ISA software backward compatibility) and the Adaptec 154x itself*/
//Note: for the Adaptec-enabled Windows NT betas, install from HDD at the moment due to a bug in the round robin outgoing
//mailboxes.
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -461,7 +458,7 @@ typedef union __attribute__((packed)) CCBU
// Adapter limits // Adapter limits
// //
#define MAX_SG_DESCRIPTORS 32 #define MAX_SG_DESCRIPTORS (scsi_model ? 32 : 17)
typedef struct __attribute__((packed)) SGE32 typedef struct __attribute__((packed)) SGE32
{ {
@@ -679,28 +676,28 @@ static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries
} }
} }
void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, CCBU *CmdBlock, int Is24bit) void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bit)
{ {
if (Is24bit) if (Is24bit)
{ {
DataPointer = ADDR_TO_U32(CmdBlock->old.DataPointer); DataPointer = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataPointer);
DataLength = ADDR_TO_U32(CmdBlock->old.DataLength); DataLength = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength);
} }
else else
{ {
DataPointer = CmdBlock->new.DataPointer; DataPointer = BuslogicRequests->CmdBlock.new.DataPointer;
DataLength = CmdBlock->new.DataLength; DataLength = BuslogicRequests->CmdBlock.new.DataLength;
} }
if (CmdBlock->common.Cdb[0] == GPCMD_TEST_UNIT_READY) if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)
DataLength = 0; DataLength = 0;
BuslogicLog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); BuslogicLog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer);
if (DataLength && CmdBlock->common.ControlByte != 0x03) if (DataLength && BuslogicRequests->CmdBlock.common.ControlByte != 0x03)
{ {
if (CmdBlock->common.Opcode == SCATTER_GATHER_COMMAND || if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND ||
CmdBlock->common.Opcode == SCATTER_GATHER_COMMAND_RES) BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)
{ {
uint32_t ScatterGatherRead; uint32_t ScatterGatherRead;
uint32_t ScatterEntry; uint32_t ScatterEntry;
@@ -729,15 +726,17 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, CCBU *CmdB
ScatterGatherAddrCurrent += ScatterGatherRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32)); ScatterGatherAddrCurrent += ScatterGatherRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32));
} while (ScatterGatherLeft > 0); } while (ScatterGatherLeft > 0);
BuslogicLog("Data to transfer (S/G) %d\n", DataToTransfer);
SCSIDevices[scsi_cdrom_id].InitLength = DataToTransfer; SCSIDevices[scsi_cdrom_id].InitLength = DataToTransfer;
SCSIDevices[scsi_cdrom_id].CmdBuffer[SCSIDevices[scsi_cdrom_id].pos++] = SCSIDevices[scsi_cdrom_id].InitLength;
//If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without //If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without
//checking its length, so do this procedure for both no read/write commands. //checking its length, so do this procedure for both no read/write commands.
if (CmdBlock->common.ControlByte == CCB_DATA_XFER_OUT || CmdBlock->common.ControlByte == 0x00) if (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT || BuslogicRequests->CmdBlock.common.ControlByte == 0x00)
{ {
ScatterGatherLeft = DataLength / (Is24bit ? sizeof(SGE) : sizeof(SGE32)); ScatterGatherLeft = DataLength / (Is24bit ? sizeof(SGE) : sizeof(SGE32));
ScatterGatherAddrCurrent = DataPointer; ScatterGatherAddrCurrent = DataPointer;
uint8_t *DataBuffer = (uint8_t *)SCSIDevices[scsi_cdrom_id].CmdBuffer;
do do
{ {
@@ -755,19 +754,19 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, CCBU *CmdB
Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer;
DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment;
DMAPageRead(Address, DataBuffer, DataToTransfer); DMAPageRead(Address, SCSIDevices[scsi_cdrom_id].CmdBuffer, DataToTransfer);
DataBuffer += DataToTransfer;
} }
ScatterGatherAddrCurrent += ScatterGatherRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32)); ScatterGatherAddrCurrent += ScatterGatherRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32));
} while (ScatterGatherLeft > 0); } while (ScatterGatherLeft > 0);
} }
} }
else if (CmdBlock->common.Opcode == SCSI_INITIATOR_COMMAND || else if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND ||
CmdBlock->common.Opcode == SCSI_INITIATOR_COMMAND_RES) BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES)
{ {
uint32_t Address = DataPointer; uint32_t Address = DataPointer;
SCSIDevices[scsi_cdrom_id].InitLength = DataLength; SCSIDevices[scsi_cdrom_id].InitLength = DataLength;
SCSIDevices[scsi_cdrom_id].CmdBuffer[SCSIDevices[scsi_cdrom_id].pos++] = SCSIDevices[scsi_cdrom_id].InitLength;
DMAPageRead(Address, SCSIDevices[scsi_cdrom_id].CmdBuffer, SCSIDevices[scsi_cdrom_id].InitLength); DMAPageRead(Address, SCSIDevices[scsi_cdrom_id].CmdBuffer, SCSIDevices[scsi_cdrom_id].InitLength);
} }
@@ -795,7 +794,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
//If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without //If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without
//checking its length, so do this procedure for both read/write commands. //checking its length, so do this procedure for both read/write commands.
if (DataLength > 0 && (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN || if (DataLength > 0 && (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN ||
BuslogicRequests->CmdBlock.common.ControlByte == 0x00)) BuslogicRequests->CmdBlock.common.ControlByte == 0x00) && BuslogicRequests->CmdBlock.common.ControlByte != 0x03)
{ {
if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND ||
BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)
@@ -805,7 +804,6 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
SGE32 ScatterGatherBuffer[MAX_SG_DESCRIPTORS]; SGE32 ScatterGatherBuffer[MAX_SG_DESCRIPTORS];
uint32_t ScatterGatherLeft = DataLength / (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); uint32_t ScatterGatherLeft = DataLength / (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32));
uint32_t ScatterGatherAddrCurrent = DataPointer; uint32_t ScatterGatherAddrCurrent = DataPointer;
uint8_t *DataBuffer = (uint8_t *)SCSIDevices[scsi_cdrom_id].CmdBuffer;
do do
{ {
@@ -824,8 +822,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer;
DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment;
DMAPageWrite(Address, DataBuffer, DataToTransfer); DMAPageWrite(Address, SCSIDevices[scsi_cdrom_id].CmdBuffer, DataToTransfer);
DataBuffer += DataToTransfer;
} }
ScatterGatherAddrCurrent += ScatterGatherRead * (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); ScatterGatherAddrCurrent += ScatterGatherRead * (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32));
@@ -839,20 +836,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
} }
} }
if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES || SCSIDevices[scsi_cdrom_id].InitLength = 0;
BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)
{
if (BuslogicRequests->Is24bit)
{
U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, SCSIDevices[scsi_cdrom_id].InitLength);
BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength));
}
else
{
BuslogicRequests->CmdBlock.new.DataLength = SCSIDevices[scsi_cdrom_id].InitLength;
BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength);
}
}
} }
uint8_t BuslogicRead(uint16_t Port, void *p) uint8_t BuslogicRead(uint16_t Port, void *p)
@@ -957,17 +941,16 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
case 0x21: case 0x21:
case 0x24: case 0x24:
case 0x25: case 0x25:
Buslogic->CmdParamLeft = 1;
break;
case 0x8B: case 0x8B:
case 0x8D: case 0x8D:
case 0x8F: case 0x8F:
case 0x96: case 0x96:
Buslogic->CmdParamLeft = 1; Buslogic->CmdParamLeft = scsi_model ? 1 : 0;
break; break;
Buslogic->CmdParamLeft = 1;
break;
case 0x91: case 0x91:
Buslogic->CmdParamLeft = 2; Buslogic->CmdParamLeft = 2;
break; break;
@@ -986,7 +969,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
break; break;
case 0x81: case 0x81:
Buslogic->CmdParamLeft = sizeof(MailboxInitExtended_t); Buslogic->CmdParamLeft = scsi_model ? sizeof(MailboxInitExtended_t) : 0;
break; break;
case 0x28: case 0x28:
@@ -1092,12 +1075,16 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
Reply->cMailbox = Buslogic->MailboxCount; Reply->cMailbox = Buslogic->MailboxCount;
U32_TO_ADDR(Reply->MailboxAddress, Buslogic->MailboxOutAddr); U32_TO_ADDR(Reply->MailboxAddress, Buslogic->MailboxOutAddr);
Reply->uSignature = 'B'; if (scsi_model)
/* The 'D' signature prevents Buslogic's OS/2 drivers from getting too {
* friendly with Adaptec hardware and upsetting the HBA state. Reply->uSignature = 'B';
*/ /* The 'D' signature prevents Buslogic's OS/2 drivers from getting too
Reply->uCharacterD = 'D'; /* BusLogic model. */ * friendly with Adaptec hardware and upsetting the HBA state.
Reply->uHostBusType = 'A'; /* ISA bus. */ */
Reply->uCharacterD = 'D'; /* BusLogic model. */
Reply->uHostBusType = 'A'; /* ISA bus. */
}
BuslogicLog("Return Setup Information: %d\n", Buslogic->CmdBuf[0]); BuslogicLog("Return Setup Information: %d\n", Buslogic->CmdBuf[0]);
} }
break; break;
@@ -1179,72 +1166,120 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
case 0x81: case 0x81:
{ {
Buslogic->Mbx24bit = 0; if (scsi_model)
{
MailboxInitExtended_t *MailboxInit = (MailboxInitExtended_t *)Buslogic->CmdBuf; Buslogic->Mbx24bit = 0;
MailboxInitExtended_t *MailboxInit = (MailboxInitExtended_t *)Buslogic->CmdBuf;
Buslogic->MailboxCount = MailboxInit->Count; Buslogic->MailboxCount = MailboxInit->Count;
Buslogic->MailboxOutAddr = MailboxInit->Address; Buslogic->MailboxOutAddr = MailboxInit->Address;
Buslogic->MailboxInAddr = MailboxInit->Address + (Buslogic->MailboxCount * sizeof(Mailbox32_t)); Buslogic->MailboxInAddr = MailboxInit->Address + (Buslogic->MailboxCount * sizeof(Mailbox32_t));
BuslogicLog("Buslogic Extended Initialize Mailbox Command\n"); BuslogicLog("Buslogic Extended Initialize Mailbox Command\n");
BuslogicLog("Mailbox Out Address=0x%08X\n", Buslogic->MailboxOutAddr); BuslogicLog("Mailbox Out Address=0x%08X\n", Buslogic->MailboxOutAddr);
BuslogicLog("Mailbox In Address=0x%08X\n", Buslogic->MailboxInAddr); BuslogicLog("Mailbox In Address=0x%08X\n", Buslogic->MailboxInAddr);
BuslogicLog("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, MailboxInit->Address); BuslogicLog("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, MailboxInit->Address);
Buslogic->Status &= ~STAT_INIT; Buslogic->Status &= ~STAT_INIT;
Buslogic->DataReplyLeft = 0; Buslogic->DataReplyLeft = 0;
}
else
{
Buslogic->DataReplyLeft = 0;
Buslogic->Status |= STAT_INVCMD;
}
} }
break; break;
case 0x84: case 0x84:
Buslogic->DataBuf[0] = '7'; if (scsi_model)
Buslogic->DataReplyLeft = 1; {
Buslogic->DataBuf[0] = '7';
Buslogic->DataReplyLeft = 1;
}
else
{
Buslogic->DataReplyLeft = 0;
Buslogic->Status |= STAT_INVCMD;
}
break; break;
case 0x85: case 0x85:
Buslogic->DataBuf[0] = 'B'; if (scsi_model)
Buslogic->DataReplyLeft = 1; {
Buslogic->DataBuf[0] = 'B';
Buslogic->DataReplyLeft = 1;
}
else
{
Buslogic->DataReplyLeft = 0;
Buslogic->Status |= STAT_INVCMD;
}
break; break;
case 0x8B: case 0x8B:
{ {
int i; if (scsi_model)
{
/* The reply length is set by the guest and is found in the first byte of the command buffer. */ int i;
Buslogic->DataReplyLeft = Buslogic->CmdBuf[0];
memset(Buslogic->DataBuf, 0, Buslogic->DataReplyLeft); /* The reply length is set by the guest and is found in the first byte of the command buffer. */
const char aModelName[] = "542B "; /* Trailing \0 is fine, that's the filler anyway. */ Buslogic->DataReplyLeft = Buslogic->CmdBuf[0];
int cCharsToTransfer = Buslogic->DataReplyLeft <= sizeof(aModelName) memset(Buslogic->DataBuf, 0, Buslogic->DataReplyLeft);
? Buslogic->DataReplyLeft const char aModelName[] = "542B "; /* Trailing \0 is fine, that's the filler anyway. */
: sizeof(aModelName); int cCharsToTransfer = Buslogic->DataReplyLeft <= sizeof(aModelName)
? Buslogic->DataReplyLeft
: sizeof(aModelName);
for (i = 0; i < cCharsToTransfer; i++) for (i = 0; i < cCharsToTransfer; i++)
Buslogic->DataBuf[i] = aModelName[i]; Buslogic->DataBuf[i] = aModelName[i];
}
else
{
Buslogic->DataReplyLeft = 0;
Buslogic->Status |= STAT_INVCMD;
}
} }
break; break;
case 0x8D: case 0x8D:
{ {
Buslogic->DataReplyLeft = Buslogic->CmdBuf[0]; if (scsi_model)
ReplyInquireExtendedSetupInformation *Reply = (ReplyInquireExtendedSetupInformation *)Buslogic->DataBuf; {
Buslogic->DataReplyLeft = Buslogic->CmdBuf[0];
ReplyInquireExtendedSetupInformation *Reply = (ReplyInquireExtendedSetupInformation *)Buslogic->DataBuf;
Reply->uBusType = 'A'; /* ISA style */ Reply->uBusType = 'A'; /* ISA style */
Reply->u16ScatterGatherLimit = 8192; Reply->u16ScatterGatherLimit = 8192;
Reply->cMailbox = Buslogic->MailboxCount; Reply->cMailbox = Buslogic->MailboxCount;
Reply->uMailboxAddressBase = Buslogic->MailboxOutAddr; Reply->uMailboxAddressBase = Buslogic->MailboxOutAddr;
memcpy(Reply->aFirmwareRevision, "07B", sizeof(Reply->aFirmwareRevision)); memcpy(Reply->aFirmwareRevision, "07B", sizeof(Reply->aFirmwareRevision));
BuslogicLog("Return Extended Setup Information: %d\n", Buslogic->CmdBuf[0]); BuslogicLog("Return Extended Setup Information: %d\n", Buslogic->CmdBuf[0]);
}
else
{
Buslogic->DataReplyLeft = 0;
Buslogic->Status |= STAT_INVCMD;
}
} }
break; break;
case 0x8F: case 0x8F:
if (Buslogic->CmdBuf[0] == 0) if (scsi_model)
Buslogic->StrictRoundRobinMode = 0; {
else if (Buslogic->CmdBuf[0] == 1) if (Buslogic->CmdBuf[0] == 0)
Buslogic->StrictRoundRobinMode = 1; Buslogic->StrictRoundRobinMode = 0;
else if (Buslogic->CmdBuf[0] == 1)
Buslogic->DataReplyLeft = 0; Buslogic->StrictRoundRobinMode = 1;
Buslogic->DataReplyLeft = 0;
}
else
{
Buslogic->DataReplyLeft = 0;
Buslogic->Status |= STAT_INVCMD;
}
break; break;
case 0x91: case 0x91:
@@ -1258,12 +1293,15 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
break; break;
case 0x96: case 0x96:
if (Buslogic->CmdBuf[0] == 0) if (scsi_model)
Buslogic->ExtendedLUNCCBFormat = 0; {
else if (Buslogic->CmdBuf[0] == 1) if (Buslogic->CmdBuf[0] == 0)
Buslogic->ExtendedLUNCCBFormat = 1; Buslogic->ExtendedLUNCCBFormat = 0;
else if (Buslogic->CmdBuf[0] == 1)
Buslogic->DataReplyLeft = 0; Buslogic->ExtendedLUNCCBFormat = 1;
Buslogic->DataReplyLeft = 0;
}
break; break;
case 0x22: //undocumented case 0x22: //undocumented
@@ -1284,11 +1322,13 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
break; break;
case 2: case 2:
Buslogic->Interrupt = Val; //For Buslogic if (scsi_model)
Buslogic->Interrupt = Val; //For Buslogic
break; break;
case 3: case 3:
Buslogic->Geometry = Val; //For Buslogic if (scsi_model)
Buslogic->Geometry = Val; //For Buslogic
break; break;
} }
} }
@@ -1345,14 +1385,13 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co
static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Mailbox32_t *Mailbox32) static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
{ {
BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests;
CCBU CmdBlock;
uint8_t Id, Lun; uint8_t Id, Lun;
//Fetch data from the Command Control Block. //Fetch data from the Command Control Block.
DMAPageRead(CCBPointer, &CmdBlock, sizeof(CCB32)); DMAPageRead(CCBPointer, &BuslogicRequests->CmdBlock, sizeof(CCB32));
BuslogicRequests->TargetID = Buslogic->Mbx24bit ? CmdBlock.old.Id : CmdBlock.new.Id; BuslogicRequests->TargetID = Buslogic->Mbx24bit ? BuslogicRequests->CmdBlock.old.Id : BuslogicRequests->CmdBlock.new.Id;
BuslogicRequests->LUN = Buslogic->Mbx24bit ? CmdBlock.old.Lun : CmdBlock.new.Lun; BuslogicRequests->LUN = Buslogic->Mbx24bit ? BuslogicRequests->CmdBlock.old.Lun : BuslogicRequests->CmdBlock.new.Lun;
Id = BuslogicRequests->TargetID; Id = BuslogicRequests->TargetID;
Lun = BuslogicRequests->LUN; Lun = BuslogicRequests->LUN;
@@ -1367,21 +1406,27 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
BuslogicRequests->CCBPointer = CCBPointer; BuslogicRequests->CCBPointer = CCBPointer;
BuslogicRequests->Is24bit = Buslogic->Mbx24bit; BuslogicRequests->Is24bit = Buslogic->Mbx24bit;
memcpy(&BuslogicRequests->CmdBlock, &CmdBlock, sizeof(CmdBlock));
if (Mailbox32->u.out.ActionCode == MBO_START) if (Mailbox32->u.out.ActionCode == MBO_START)
{ {
BuslogicSenseBufferAllocate(BuslogicRequests); BuslogicSenseBufferAllocate(BuslogicRequests);
BuslogicDataBufferAllocate(BuslogicRequests, &BuslogicRequests->CmdBlock, BuslogicRequests->Is24bit); BuslogicDataBufferAllocate(BuslogicRequests, BuslogicRequests->Is24bit);
uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength); uint32_t i;
BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]);
for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++)
BuslogicLog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]);
BuslogicLog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte);
BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength);
BuslogicLog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode);
if ((CmdBlock.common.ControlByte != 0x03) && (CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND)) if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND))
{ {
if (cdrom->medium_changed()) if (cdrom->medium_changed())
{ {
pclog("Media changed\n"); BuslogicLog("Media changed\n");
SCSICDROM_Insert(); SCSICDROM_Insert();
} }
@@ -1433,42 +1478,44 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
return; return;
} }
} }
uint32_t i;
BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]);
for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++)
BuslogicLog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]);
BuslogicLog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte);
BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength);
BuslogicLog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode);
//First, get the data buffer otherwise putting it after the //First, get the data buffer otherwise putting it after the
//exec function results into not getting read/write commands right and //exec function results into not getting read/write commands right and
//failing to detect the device. //failing to detect the device.
if (CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) if (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN)
{ {
SCSIRead(Id, SCSIDevices[Id].InitLength); SCSIRead(Id, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].InitLength);
} }
else if (CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) else if (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT)
{ {
SCSIWrite(Id, SCSIDevices[Id].InitLength); SCSIWrite(Id, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].InitLength);
} }
//Finally, execute the SCSI command immediately and get the transfer length. //Finally, execute the SCSI command immediately and get the transfer length.
SCSIPhase = SCSI_PHASE_COMMAND; SCSIPhase = SCSI_PHASE_COMMAND;
SCSIExecCommand(Id, BuslogicRequests->CmdBlock.common.Cdb, SenseLength); SCSIExecCommand(Id, SCSIDevices[Id].CmdBuffer, BuslogicRequests->CmdBlock.common.Cdb);
SCSIGetLength(Id, &SCSIDevices[Id].InitLength); SCSIGetLength(Id, &SCSIDevices[Id].InitLength);
if (SCSIPhase == SCSI_PHASE_DATAIN) if (SCSIPhase == SCSI_PHASE_DATAIN)
{ {
SCSIReadData(Id, BuslogicRequests->CmdBlock.common.Cdb, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].InitLength,SenseLength); SCSIReadData(Id, BuslogicRequests->CmdBlock.common.Cdb, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].InitLength);
}
else if (SCSIPhase == SCSI_PHASE_DATAOUT)
{
if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_MODE_SELECT_6 ||
BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_MODE_SELECT_10)
{
//Mode Sense/Select stuff
if ((SCSIDevices[Id].pos >= prefix_len+4) && (page_flags[page_current] & PAGE_CHANGEABLE))
{
mode_pages_in[page_current][SCSIDevices[Id].pos - prefix_len - 4] = SCSIDevices[Id].CmdBuffer[SCSIDevices[Id].pos - 2];
mode_pages_in[page_current][SCSIDevices[Id].pos - prefix_len - 3] = SCSIDevices[Id].CmdBuffer[SCSIDevices[Id].pos - 1];
}
}
} }
BuslogicDataBufferFree(BuslogicRequests); BuslogicDataBufferFree(BuslogicRequests);
if (BuslogicRequests->RequestSenseBuffer) if (BuslogicRequests->RequestSenseBuffer)
@@ -1476,7 +1523,23 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
} }
BuslogicLog("Request complete\n"); BuslogicLog("Request complete\n");
BuslogicLog("SCSI Status %002X, Sense %02X, Asc %02X, Ascq %02X\n", SCSIStatus, SCSISense.SenseKey, SCSISense.Asc, SCSISense.Ascq); BuslogicLog("SCSI Status %02X, Sense %02X, Asc %02X, Ascq %02X\n", SCSIStatus, SCSISense.SenseKey, SCSISense.Asc, SCSISense.Ascq);
if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES ||
BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)
{
if (BuslogicRequests->Is24bit)
{
U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, SCSIDevices[Id].InitLength);
BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength));
}
else
{
BuslogicRequests->CmdBlock.new.DataLength = SCSIDevices[Id].InitLength;
BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength);
}
}
if (SCSIStatus == SCSI_STATUS_OK) if (SCSIStatus == SCSI_STATUS_OK)
{ {
@@ -1491,15 +1554,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
} }
else else
{ {
if (Mailbox32->u.out.ActionCode == MBO_START) BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR);
{
BuslogicDataBufferFree(BuslogicRequests);
if (BuslogicRequests->RequestSenseBuffer)
BuslogicSenseBufferFree(BuslogicRequests, 1);
}
BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR);
if (Mailbox32->u.out.ActionCode == MBO_START) if (Mailbox32->u.out.ActionCode == MBO_START)
BuslogicStartMailbox(Buslogic); BuslogicStartMailbox(Buslogic);
@@ -1610,11 +1665,11 @@ void BuslogicClose(void *p)
device_t BuslogicDevice = device_t BuslogicDevice =
{ {
"Buslogic BT-542B", "Adaptec/Buslogic",
0, 0,
BuslogicInit, BuslogicInit,
BuslogicClose, BuslogicClose,
NULL,//BuslogicAvailable, NULL,
NULL, NULL,
NULL, NULL,
NULL NULL

View File

@@ -23,9 +23,9 @@ void SCSIGetLength(uint8_t id, int *datalen)
} }
//Execute SCSI command //Execute SCSI command
void SCSIExecCommand(uint8_t id, uint8_t *cdb, uint8_t sense) void SCSIExecCommand(uint8_t id, uint8_t *buffer, uint8_t *cdb)
{ {
SCSICDROM_Command(id, cdb, sense); SCSICDROM_Command(id, buffer, cdb);
} }
//Read pending data from the resulting SCSI command //Read pending data from the resulting SCSI command
@@ -42,7 +42,7 @@ void SCSIDMAResetPosition(uint8_t Id)
} }
//Read data from buffer with given position in buffer memory //Read data from buffer with given position in buffer memory
void SCSIRead(uint8_t Id, uint32_t len_size) void SCSIRead(uint8_t Id, uint8_t *dstbuf, uint8_t *srcbuf, uint32_t len_size)
{ {
if (!len_size) //If there's no data, don't try to do anything. if (!len_size) //If there's no data, don't try to do anything.
return; return;
@@ -51,7 +51,7 @@ void SCSIRead(uint8_t Id, uint32_t len_size)
for (c = 0; c <= len_size; c++) //Count as many bytes as the length of the buffer is requested for (c = 0; c <= len_size; c++) //Count as many bytes as the length of the buffer is requested
{ {
memcpy(SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].CmdBuffer + SCSIDevices[Id].pos, len_size); memcpy(dstbuf, srcbuf + SCSIDevices[Id].pos, len_size);
SCSIDevices[Id].pos = c; SCSIDevices[Id].pos = c;
//pclog("SCSI Read: position at %i\n", SCSIDevices[Id].pos); //pclog("SCSI Read: position at %i\n", SCSIDevices[Id].pos);
@@ -59,24 +59,14 @@ void SCSIRead(uint8_t Id, uint32_t len_size)
} }
//Write data to buffer with given position in buffer memory //Write data to buffer with given position in buffer memory
void SCSIWrite(uint8_t Id, uint32_t len_size) void SCSIWrite(uint8_t Id, uint8_t *srcbuf, uint8_t *dstbuf, uint32_t len_size)
{ {
if (!len_size) //If there's no data, don't try to do anything.
return;
int c; int c;
for (c = 0; c <= len_size; c++) //Count as many bytes as the length of the buffer is requested for (c = 0; c <= len_size; c++) //Count as many bytes as the length of the buffer is requested
{ {
memcpy(SCSIDevices[Id].CmdBuffer + SCSIDevices[Id].pos, SCSIDevices[Id].CmdBuffer, len_size); memcpy(srcbuf + SCSIDevices[Id].pos, dstbuf, len_size);
SCSIDevices[Id].pos = c; SCSIDevices[Id].pos = c;
//Mode Sense/Select stuff
if ((SCSIDevices[Id].pos >= prefix_len+4) && (page_flags[page_current] & PAGE_CHANGEABLE))
{
mode_pages_in[page_current][SCSIDevices[Id].pos - prefix_len - 4] = SCSIDevices[Id].CmdBuffer[SCSIDevices[Id].pos - 2];
mode_pages_in[page_current][SCSIDevices[Id].pos - prefix_len - 3] = SCSIDevices[Id].CmdBuffer[SCSIDevices[Id].pos - 1];
}
//pclog("SCSI Write: position at %i\n", SCSIDevices[Id].pos); //pclog("SCSI Write: position at %i\n", SCSIDevices[Id].pos);
} }

View File

@@ -171,6 +171,8 @@ uint32_t DataPointer;
int SectorLBA; int SectorLBA;
int SectorLen; int SectorLen;
int MediaPresent;
extern uint8_t SCSIStatus; extern uint8_t SCSIStatus;
extern uint8_t SCSIPhase; extern uint8_t SCSIPhase;
extern int SCSICallback[16]; extern int SCSICallback[16];
@@ -178,6 +180,8 @@ extern uint8_t scsi_cdrom_id;
struct struct
{ {
uint8_t SenseBuffer[18];
uint8_t SenseLength;
uint8_t UnitAttention; uint8_t UnitAttention;
uint8_t SenseKey; uint8_t SenseKey;
uint8_t Asc; uint8_t Asc;
@@ -245,9 +249,8 @@ extern int cdrom_sector_size, cdrom_sector_ismsf;
struct struct
{ {
int lba_pos, lba_len;
uint32_t pos; uint32_t pos;
uint8_t CmdBuffer[262144]; uint8_t CmdBuffer[512*512];
uint32_t CmdBufferLength; uint32_t CmdBufferLength;
int LunType; int LunType;
uint32_t InitLength; uint32_t InitLength;

View File

@@ -642,8 +642,9 @@ int cdrom_read_data(uint8_t *buffer)
void SCSIClearSense(uint8_t Command, uint8_t IgnoreUA) void SCSIClearSense(uint8_t Command, uint8_t IgnoreUA)
{ {
if ((SCSISense.SenseKey == SENSE_UNIT_ATTENTION) || IgnoreUA) if ((SCSISense.SenseKey == SENSE_UNIT_ATTENTION) || IgnoreUA || (SCSISense.SenseKey == SENSE_ILLEGAL_REQUEST && SCSISense.Asc == ASC_INV_FIELD_IN_CMD_PACKET))
{ {
pclog("Sense cleared\n");
ScsiPrev=Command; ScsiPrev=Command;
SCSISenseCodeOk(); SCSISenseCodeOk();
} }
@@ -678,65 +679,7 @@ static int SCSICDROM_TOC(uint8_t id, uint8_t *cdb)
return TocFormat; return TocFormat;
} }
void SCSICDROMRequestSense(uint8_t id, uint8_t *cdb, uint8_t sense) void SCSICDROM_Command(uint8_t id, uint8_t *cmdbuffer, uint8_t *cdb)
{
/*Will return 18 bytes of 0*/
memset(SCSIDevices[id].CmdBuffer,0,512);
SCSIDevices[id].CmdBuffer[0]=0x80|0x70;
if ((SCSISense.SenseKey > 0) || (cd_status < CD_STATUS_PLAYING))
{
if (SenseCompleted)
{
SCSIDevices[id].CmdBuffer[2]=SENSE_ILLEGAL_REQUEST;
SCSIDevices[id].CmdBuffer[12]=ASC_AUDIO_PLAY_OPERATION;
SCSIDevices[id].CmdBuffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED;
}
else
{
SCSIDevices[id].CmdBuffer[2]=SCSISense.SenseKey;
SCSIDevices[id].CmdBuffer[12]=SCSISense.Asc;
SCSIDevices[id].CmdBuffer[13]=SCSISense.Ascq;
}
}
else if ((SCSISense.SenseKey == 0) && (cd_status >= CD_STATUS_PLAYING) && (cd_status != CD_STATUS_STOPPED))
{
SCSIDevices[id].CmdBuffer[2]=SENSE_ILLEGAL_REQUEST;
SCSIDevices[id].CmdBuffer[12]=ASC_AUDIO_PLAY_OPERATION;
SCSIDevices[id].CmdBuffer[13]=(cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED;
}
else
{
if (SCSISense.UnitAttention)
{
SCSIDevices[id].CmdBuffer[2]=SENSE_UNIT_ATTENTION;
SCSIDevices[id].CmdBuffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED;
SCSIDevices[id].CmdBuffer[13]=0;
}
}
SCSIDevices[id].CmdBuffer[7]=10;
SCSIPhase = SCSI_PHASE_DATAIN;
SCSIStatus = SCSI_STATUS_OK;
SCSICallback[id]=60*SCSI_TIME;
SCSIDevices[id].CmdBufferLength = sense;
SCSIDMAResetPosition(id);
if (SCSIDevices[id].CmdBuffer[2] == SENSE_UNIT_ATTENTION)
{
/* If the last remaining sense is unit attention, clear
that condition. */
SCSISense.UnitAttention = 0;
}
/* Clear the sense stuff as per the spec. */
SCSIClearSense(cdb[0], 0);
}
void SCSICDROM_Command(uint8_t id, uint8_t *cdb, uint8_t sense)
{ {
int len; int len;
int pos=0; int pos=0;
@@ -754,7 +697,7 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb, uint8_t sense)
int ret = 0; int ret = 0;
msf = cdb[1] & 2; msf = cdb[1] & 2;
prev_status = cd_status; prev_status = cd_status;
cd_status = cdrom->status(); cd_status = cdrom->status();
if (((prev_status == CD_STATUS_PLAYING) || (prev_status == CD_STATUS_PAUSED)) && ((cd_status != CD_STATUS_PLAYING) && (cd_status != CD_STATUS_PAUSED))) if (((prev_status == CD_STATUS_PLAYING) || (prev_status == CD_STATUS_PAUSED)) && ((cd_status != CD_STATUS_PLAYING) && (cd_status != CD_STATUS_PAUSED)))
@@ -764,7 +707,7 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb, uint8_t sense)
else else
{ {
SenseCompleted = 0; SenseCompleted = 0;
} }
switch (cdb[0]) switch (cdb[0])
{ {
@@ -775,8 +718,63 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb, uint8_t sense)
break; break;
case GPCMD_REQUEST_SENSE: case GPCMD_REQUEST_SENSE:
SCSICDROMRequestSense(id, cdb, sense); len = cdb[4];
break;
/*Will return 18 bytes of 0*/
memset(cmdbuffer,0,512);
cmdbuffer[0]=0x80|0x70;
if ((SCSISense.SenseKey > 0) || (cd_status < CD_STATUS_PLAYING))
{
if (SenseCompleted)
{
cmdbuffer[2]=SENSE_ILLEGAL_REQUEST;
cmdbuffer[12]=ASC_AUDIO_PLAY_OPERATION;
cmdbuffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED;
}
else
{
cmdbuffer[2]=SCSISense.SenseKey;
cmdbuffer[12]=SCSISense.Asc;
cmdbuffer[13]=SCSISense.Ascq;
}
}
else if ((SCSISense.SenseKey == 0) && (cd_status >= CD_STATUS_PLAYING) && (cd_status != CD_STATUS_STOPPED))
{
cmdbuffer[2]=SENSE_ILLEGAL_REQUEST;
cmdbuffer[12]=ASC_AUDIO_PLAY_OPERATION;
cmdbuffer[13]=(cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED;
}
else
{
if (SCSISense.UnitAttention)
{
cmdbuffer[2]=SENSE_UNIT_ATTENTION;
cmdbuffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED;
cmdbuffer[13]=0;
}
}
cmdbuffer[7]=10;
SCSIPhase = SCSI_PHASE_DATAIN;
SCSIStatus = SCSI_STATUS_OK;
SCSICallback[id]=60*SCSI_TIME;
SCSIDevices[id].CmdBufferLength = len;
SCSIDMAResetPosition(id);
if (cmdbuffer[2] == SENSE_UNIT_ATTENTION)
{
/* If the last remaining sense is unit attention, clear
that condition. */
SCSISense.UnitAttention = 0;
}
/* Clear the sense stuff as per the spec. */
SCSIClearSense(cdb[0], 0);
return;
case GPCMD_READ_6: case GPCMD_READ_6:
case GPCMD_READ_10: case GPCMD_READ_10:
@@ -837,7 +835,7 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb, uint8_t sense)
{ {
pos = (cdb[2]<<24)|(cdb[3]<<16)|(cdb[4]<<8)|cdb[5]; pos = (cdb[2]<<24)|(cdb[3]<<16)|(cdb[4]<<8)|cdb[5];
} }
cdrom->seek(SCSIDevices[id].lba_pos); cdrom->seek(pos);
SCSIPhase = SCSI_PHASE_STATUS; SCSIPhase = SCSI_PHASE_STATUS;
SCSIStatus = SCSI_STATUS_OK; SCSIStatus = SCSI_STATUS_OK;
@@ -846,23 +844,24 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb, uint8_t sense)
case GPCMD_INQUIRY: case GPCMD_INQUIRY:
max_length = cdb[4]; max_length = cdb[4];
len = max_length;
if (cdb[1] & 1) if (cdb[1] & 1)
{ {
PreambleLen = 4; PreambleLen = 4;
SizeIndex = 3; SizeIndex = 3;
SCSIDevices[id].CmdBuffer[Idx++] = 05; cmdbuffer[Idx++] = 05;
SCSIDevices[id].CmdBuffer[Idx++] = cdb[2]; cmdbuffer[Idx++] = cdb[2];
SCSIDevices[id].CmdBuffer[Idx++] = 0; cmdbuffer[Idx++] = 0;
Idx++; Idx++;
switch (cdb[2]) switch (cdb[2])
{ {
case 0x00: case 0x00:
SCSIDevices[id].CmdBuffer[Idx++] = 0x00; cmdbuffer[Idx++] = 0x00;
SCSIDevices[id].CmdBuffer[Idx++] = 0x83; cmdbuffer[Idx++] = 0x83;
break; break;
case 0x83: case 0x83:
@@ -873,26 +872,26 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb, uint8_t sense)
SCSICallback[id]=50*SCSI_TIME; SCSICallback[id]=50*SCSI_TIME;
return; return;
} }
SCSIDevices[id].CmdBuffer[Idx++] = 0x02; cmdbuffer[Idx++] = 0x02;
SCSIDevices[id].CmdBuffer[Idx++] = 0x00; cmdbuffer[Idx++] = 0x00;
SCSIDevices[id].CmdBuffer[Idx++] = 0x00; cmdbuffer[Idx++] = 0x00;
SCSIDevices[id].CmdBuffer[Idx++] = 20; cmdbuffer[Idx++] = 20;
ScsiPadStr8(SCSIDevices[id].CmdBuffer + Idx, 20, "53R141"); /* Serial */ ScsiPadStr8(cmdbuffer + Idx, 20, "53R141"); /* Serial */
Idx += 20; Idx += 20;
if (Idx + 72 > SCSIDevices[id].CmdBufferLength) if (Idx + 72 > max_length)
{ {
goto SCSIOut; goto SCSIOut;
} }
SCSIDevices[id].CmdBuffer[Idx++] = 0x02; cmdbuffer[Idx++] = 0x02;
SCSIDevices[id].CmdBuffer[Idx++] = 0x01; cmdbuffer[Idx++] = 0x01;
SCSIDevices[id].CmdBuffer[Idx++] = 0x00; cmdbuffer[Idx++] = 0x00;
SCSIDevices[id].CmdBuffer[Idx++] = 68; cmdbuffer[Idx++] = 68;
ScsiPadStr8(SCSIDevices[id].CmdBuffer + Idx, 8, "86Box"); /* Vendor */ ScsiPadStr8(cmdbuffer + Idx, 8, "86Box"); /* Vendor */
Idx += 8; Idx += 8;
ScsiPadStr8(SCSIDevices[id].CmdBuffer + Idx, 40, "86BoxCD 1.00"); /* Product */ ScsiPadStr8(cmdbuffer + Idx, 40, "86BoxCD 1.00"); /* Product */
Idx += 40; Idx += 40;
ScsiPadStr8(SCSIDevices[id].CmdBuffer + Idx, 20, "53R141"); /* Product */ ScsiPadStr8(cmdbuffer + Idx, 20, "53R141"); /* Product */
Idx += 20; Idx += 20;
break; break;
@@ -908,23 +907,23 @@ void SCSICDROM_Command(uint8_t id, uint8_t *cdb, uint8_t sense)
PreambleLen = 5; PreambleLen = 5;
SizeIndex = 4; SizeIndex = 4;
SCSIDevices[id].CmdBuffer[0] = 0x05; /*CD-ROM*/ cmdbuffer[0] = 0x05; /*CD-ROM*/
SCSIDevices[id].CmdBuffer[1] = 0x80; /*Removable*/ cmdbuffer[1] = 0x80; /*Removable*/
SCSIDevices[id].CmdBuffer[2] = 0; cmdbuffer[2] = 0;
SCSIDevices[id].CmdBuffer[3] = 0x21; cmdbuffer[3] = 0x21;
SCSIDevices[id].CmdBuffer[4] = 31; cmdbuffer[4] = 31;
SCSIDevices[id].CmdBuffer[5] = 0; cmdbuffer[5] = 0;
SCSIDevices[id].CmdBuffer[6] = 0; cmdbuffer[6] = 0;
SCSIDevices[id].CmdBuffer[7] = 0; cmdbuffer[7] = 0;
ScsiPadStr8(SCSIDevices[id].CmdBuffer + 8, 8, "86Box"); /* Vendor */ ScsiPadStr8(cmdbuffer + 8, 8, "86Box"); /* Vendor */
ScsiPadStr8(SCSIDevices[id].CmdBuffer + 16, 16, "86BoxCD"); /* Product */ ScsiPadStr8(cmdbuffer + 16, 16, "86BoxCD"); /* Product */
ScsiPadStr8(SCSIDevices[id].CmdBuffer + 32, 4, emulator_version); /* Revision */ ScsiPadStr8(cmdbuffer + 32, 4, emulator_version); /* Revision */
Idx = 36; Idx = 36;
} }
SCSIOut: SCSIOut:
SCSIDevices[id].CmdBuffer[SizeIndex] = Idx - PreambleLen; cmdbuffer[SizeIndex] = Idx - PreambleLen;
len=Idx; len=Idx;
SCSIPhase = SCSI_PHASE_DATAIN; SCSIPhase = SCSI_PHASE_DATAIN;
@@ -950,8 +949,8 @@ SCSIOut:
page_current = cdb[2]; page_current = cdb[2];
if (page_flags[page_current] & PAGE_CHANGEABLE) if (page_flags[page_current] & PAGE_CHANGEABLE)
page_flags[GPMODE_CDROM_AUDIO_PAGE] |= PAGE_CHANGED; page_flags[GPMODE_CDROM_AUDIO_PAGE] |= PAGE_CHANGED;
SCSIPhase = SCSI_PHASE_DATAOUT; SCSIPhase = SCSI_PHASE_DATAOUT;
SCSIStatus = SCSI_STATUS_OK; SCSIStatus = SCSI_STATUS_OK;
SCSICallback[id]=60*SCSI_TIME; SCSICallback[id]=60*SCSI_TIME;
@@ -969,7 +968,7 @@ SCSIOut:
Temp = cdb[2] & 0x3F; Temp = cdb[2] & 0x3F;
memset(SCSIDevices[id].CmdBuffer, 0, len); memset(cmdbuffer, 0, len);
if (!(mode_sense_pages[cdb[2] & 0x3f] & IMPLEMENTED)) if (!(mode_sense_pages[cdb[2] & 0x3f] & IMPLEMENTED))
{ {
@@ -981,23 +980,23 @@ SCSIOut:
if (cdb[0] == GPCMD_MODE_SENSE_6) if (cdb[0] == GPCMD_MODE_SENSE_6)
{ {
len = SCSICDROMModeSense(SCSIDevices[id].CmdBuffer, 4, Temp); len = SCSICDROMModeSense(cmdbuffer, 4, Temp);
SCSIDevices[id].CmdBuffer[0] = len - 1; cmdbuffer[0] = len - 1;
SCSIDevices[id].CmdBuffer[1] = 3; /*120mm data CD-ROM*/ cmdbuffer[1] = 3; /*120mm data CD-ROM*/
} }
else else
{ {
len = SCSICDROMModeSense(SCSIDevices[id].CmdBuffer, 8, Temp); len = SCSICDROMModeSense(cmdbuffer, 8, Temp);
SCSIDevices[id].CmdBuffer[0] = (len - 2)>>8; cmdbuffer[0] = (len - 2)>>8;
SCSIDevices[id].CmdBuffer[1] = (len - 2)&255; cmdbuffer[1] = (len - 2)&255;
SCSIDevices[id].CmdBuffer[2] = 3; /*120mm data CD-ROM*/ cmdbuffer[2] = 3; /*120mm data CD-ROM*/
} }
SCSIPhase = SCSI_PHASE_DATAIN; SCSIPhase = SCSI_PHASE_DATAIN;
SCSIStatus = SCSI_STATUS_OK; SCSIStatus = SCSI_STATUS_OK;
SCSICallback[id]=60*SCSI_TIME; SCSICallback[id]=60*SCSI_TIME;
SCSIDevices[id].CmdBufferLength = len; SCSIDevices[id].CmdBufferLength = len;
SCSIDMAResetPosition(id); SCSIDMAResetPosition(id);
return; return;
@@ -1027,17 +1026,17 @@ SCSIOut:
case GPCMD_READ_CDROM_CAPACITY: case GPCMD_READ_CDROM_CAPACITY:
if (cdrom->read_capacity) if (cdrom->read_capacity)
{ {
cdrom->read_capacity(SCSIDevices[id].CmdBuffer); cdrom->read_capacity(cmdbuffer);
} }
else else
{ {
Size = cdrom->size() - 1; /* IMPORTANT: What's returned is the last LBA block. */ Size = cdrom->size() - 1; /* IMPORTANT: What's returned is the last LBA block. */
memset(SCSIDevices[id].CmdBuffer, 0, 8); memset(cmdbuffer, 0, 8);
SCSIDevices[id].CmdBuffer[0] = (Size >> 24) & 0xff; cmdbuffer[0] = (Size >> 24) & 0xff;
SCSIDevices[id].CmdBuffer[1] = (Size >> 16) & 0xff; cmdbuffer[1] = (Size >> 16) & 0xff;
SCSIDevices[id].CmdBuffer[2] = (Size >> 8) & 0xff; cmdbuffer[2] = (Size >> 8) & 0xff;
SCSIDevices[id].CmdBuffer[3] = Size & 0xff; cmdbuffer[3] = Size & 0xff;
SCSIDevices[id].CmdBuffer[6] = 8; /* 2048 = 0x0800 */ cmdbuffer[6] = 8; /* 2048 = 0x0800 */
} }
SCSIPhase = SCSI_PHASE_DATAIN; SCSIPhase = SCSI_PHASE_DATAIN;
@@ -1059,11 +1058,11 @@ SCSIOut:
} }
pos = 0; pos = 0;
SCSIDevices[id].CmdBuffer[pos++] = 0; cmdbuffer[pos++] = 0;
SCSIDevices[id].CmdBuffer[pos++] = 0; /*Audio status*/ cmdbuffer[pos++] = 0; /*Audio status*/
SCSIDevices[id].CmdBuffer[pos++] = 0; SCSIDevices[id].CmdBuffer[pos++] = 0; /*Subchannel length*/ cmdbuffer[pos++] = 0; cmdbuffer[pos++] = 0; /*Subchannel length*/
SCSIDevices[id].CmdBuffer[pos++] = 1; /*Format code*/ cmdbuffer[pos++] = 1; /*Format code*/
SCSIDevices[id].CmdBuffer[1] = cdrom->getcurrentsubchannel(&SCSIDevices[id].CmdBuffer[5], msf); cmdbuffer[1] = cdrom->getcurrentsubchannel(&cmdbuffer[5], msf);
len = 16; len = 16;
if (!Temp) if (!Temp)
len = 4; len = 4;
@@ -1081,19 +1080,19 @@ SCSIOut:
{ {
case 0: /*Normal*/ case 0: /*Normal*/
len = cdb[8]|(cdb[7]<<8); len = cdb[8]|(cdb[7]<<8);
len = cdrom->readtoc(SCSIDevices[id].CmdBuffer, cdb[6], msf, len, 0); len = cdrom->readtoc(cmdbuffer, cdb[6], msf, len, 0);
break; break;
case 1: /*Multi session*/ case 1: /*Multi session*/
len = cdb[8]|(cdb[7]<<8); len = cdb[8]|(cdb[7]<<8);
len = cdrom->readtoc_session(SCSIDevices[id].CmdBuffer, msf, len); len = cdrom->readtoc_session(cmdbuffer, msf, len);
SCSIDevices[id].CmdBuffer[0] = 0; cmdbuffer[0] = 0;
SCSIDevices[id].CmdBuffer[1] = 0xA; cmdbuffer[1] = 0xA;
break; break;
case 2: /*Raw*/ case 2: /*Raw*/
len = cdb[8]|(cdb[7]<<8); len = cdb[8]|(cdb[7]<<8);
len = cdrom->readtoc_raw(SCSIDevices[id].CmdBuffer, msf, len); len = cdrom->readtoc_raw(cmdbuffer, msf, len);
break; break;
default: default:
@@ -1113,7 +1112,7 @@ SCSIOut:
case GPCMD_READ_HEADER: case GPCMD_READ_HEADER:
if (cdrom->read_header) if (cdrom->read_header)
{ {
cdrom->read_header(cdb, SCSIDevices[id].CmdBuffer); cdrom->read_header(cdb, cmdbuffer);
} }
else else
{ {
@@ -1127,12 +1126,12 @@ SCSIOut:
{ {
real_pos = SectorLBA; real_pos = SectorLBA;
} }
SCSIDevices[id].CmdBuffer[4] = (real_pos >> 24); cmdbuffer[4] = (real_pos >> 24);
SCSIDevices[id].CmdBuffer[5] = ((real_pos >> 16) & 0xff); cmdbuffer[5] = ((real_pos >> 16) & 0xff);
SCSIDevices[id].CmdBuffer[6] = ((real_pos >> 8) & 0xff); cmdbuffer[6] = ((real_pos >> 8) & 0xff);
SCSIDevices[id].CmdBuffer[7] = real_pos & 0xff; cmdbuffer[7] = real_pos & 0xff;
SCSIDevices[id].CmdBuffer[0]=1; /*2048 bytes user data*/ cmdbuffer[0]=1; /*2048 bytes user data*/
SCSIDevices[id].CmdBuffer[1]=SCSIDevices[id].CmdBuffer[2]=SCSIDevices[id].CmdBuffer[3]=0; cmdbuffer[1]=cmdbuffer[2]=cmdbuffer[3]=0;
} }
SCSIPhase = SCSI_PHASE_DATAIN; SCSIPhase = SCSI_PHASE_DATAIN;
@@ -1165,6 +1164,7 @@ SCSIOut:
if ((cdrom_drive < 1) || (cdrom_drive == 200) || (cd_status <= CD_STATUS_DATA_ONLY) || if ((cdrom_drive < 1) || (cdrom_drive == 200) || (cd_status <= CD_STATUS_DATA_ONLY) ||
!cdrom->is_track_audio(pos, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0)) !cdrom->is_track_audio(pos, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0))
{ {
pclog("Invalid mode for this track\n");
SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_MODE_FOR_THIS_TRACK, 0x00); SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_MODE_FOR_THIS_TRACK, 0x00);
SCSICallback[id]=50*SCSI_TIME; SCSICallback[id]=50*SCSI_TIME;
@@ -1201,29 +1201,29 @@ SCSIOut:
if (len > 512) /* XXX: assume 1 sector */ if (len > 512) /* XXX: assume 1 sector */
len = 512; len = 512;
memset(SCSIDevices[id].CmdBuffer, 0, len); memset(cmdbuffer, 0, len);
/* /*
* the number of sectors from the media tells us which profile * the number of sectors from the media tells us which profile
* to use as current. 0 means there is no media * to use as current. 0 means there is no media
*/ */
if (len > CD_MAX_SECTORS ) if (len > CD_MAX_SECTORS )
{ {
SCSIDevices[id].CmdBuffer[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; cmdbuffer[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff;
SCSIDevices[id].CmdBuffer[7] = MMC_PROFILE_DVD_ROM & 0xff; cmdbuffer[7] = MMC_PROFILE_DVD_ROM & 0xff;
} }
else if (len <= CD_MAX_SECTORS) else if (len <= CD_MAX_SECTORS)
{ {
SCSIDevices[id].CmdBuffer[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; cmdbuffer[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff;
SCSIDevices[id].CmdBuffer[7] = MMC_PROFILE_CD_ROM & 0xff; cmdbuffer[7] = MMC_PROFILE_CD_ROM & 0xff;
} }
SCSIDevices[id].CmdBuffer[10] = 0x02 | 0x01; /* persistent and current */ cmdbuffer[10] = 0x02 | 0x01; /* persistent and current */
len = 12; /* headers: 8 + 4 */ len = 12; /* headers: 8 + 4 */
len += SCSICDROMSetProfile(SCSIDevices[id].CmdBuffer, &Index, MMC_PROFILE_DVD_ROM); len += SCSICDROMSetProfile(cmdbuffer, &Index, MMC_PROFILE_DVD_ROM);
len += SCSICDROMSetProfile(SCSIDevices[id].CmdBuffer, &Index, MMC_PROFILE_CD_ROM); len += SCSICDROMSetProfile(cmdbuffer, &Index, MMC_PROFILE_CD_ROM);
SCSIDevices[id].CmdBuffer[0] = ((len-4) >> 24) & 0xff; cmdbuffer[0] = ((len-4) >> 24) & 0xff;
SCSIDevices[id].CmdBuffer[1] = ((len-4) >> 16) & 0xff; cmdbuffer[1] = ((len-4) >> 16) & 0xff;
SCSIDevices[id].CmdBuffer[2] = ((len-4) >> 8) & 0xff; cmdbuffer[2] = ((len-4) >> 8) & 0xff;
SCSIDevices[id].CmdBuffer[3] = (len-4) & 0xff; cmdbuffer[3] = (len-4) & 0xff;
SCSIPhase = SCSI_PHASE_DATAIN; SCSIPhase = SCSI_PHASE_DATAIN;
SCSIStatus = SCSI_STATUS_OK; SCSIStatus = SCSI_STATUS_OK;
@@ -1235,7 +1235,7 @@ SCSIOut:
case GPCMD_GET_EVENT_STATUS_NOTIFICATION: case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
gesn_cdb = (void *)cdb; gesn_cdb = (void *)cdb;
gesn_event_header = (void *)SCSIDevices[id].CmdBuffer; gesn_event_header = (void *)cmdbuffer;
/* It is fine by the MMC spec to not support async mode operations */ /* It is fine by the MMC spec to not support async mode operations */
if (!(gesn_cdb->polled & 0x01)) if (!(gesn_cdb->polled & 0x01))
@@ -1274,7 +1274,7 @@ SCSIOut:
if (gesn_cdb->class & (1 << GESN_MEDIA)) if (gesn_cdb->class & (1 << GESN_MEDIA))
{ {
gesn_event_header->notification_class |= GESN_MEDIA; gesn_event_header->notification_class |= GESN_MEDIA;
len = SCSICDROMEventStatus(SCSIDevices[id].CmdBuffer); len = SCSICDROMEventStatus(cmdbuffer);
} }
else else
{ {
@@ -1309,18 +1309,18 @@ SCSIOut:
case GPCMD_READ_DISC_INFORMATION: case GPCMD_READ_DISC_INFORMATION:
if (cdrom->read_disc_information) if (cdrom->read_disc_information)
{ {
cdrom->read_disc_information(SCSIDevices[id].CmdBuffer); cdrom->read_disc_information(cmdbuffer);
} }
else else
{ {
SCSIDevices[id].CmdBuffer[1] = 32; cmdbuffer[1] = 32;
SCSIDevices[id].CmdBuffer[2] = 0xe; /* last session complete, disc finalized */ cmdbuffer[2] = 0xe; /* last session complete, disc finalized */
SCSIDevices[id].CmdBuffer[3] = 1; /* first track on disc */ cmdbuffer[3] = 1; /* first track on disc */
SCSIDevices[id].CmdBuffer[4] = 1; /* # of sessions */ cmdbuffer[4] = 1; /* # of sessions */
SCSIDevices[id].CmdBuffer[5] = 1; /* first track of last session */ cmdbuffer[5] = 1; /* first track of last session */
SCSIDevices[id].CmdBuffer[6] = 1; /* last track of last session */ cmdbuffer[6] = 1; /* last track of last session */
SCSIDevices[id].CmdBuffer[7] = 0x20; /* unrestricted use */ cmdbuffer[7] = 0x20; /* unrestricted use */
SCSIDevices[id].CmdBuffer[8] = 0x00; /* CD-ROM */ cmdbuffer[8] = 0x00; /* CD-ROM */
} }
SCSIPhase = SCSI_PHASE_DATAIN; SCSIPhase = SCSI_PHASE_DATAIN;
@@ -1343,7 +1343,7 @@ SCSIOut:
if (cdrom->read_track_information) if (cdrom->read_track_information)
{ {
ret = cdrom->read_track_information(cdb, SCSIDevices[id].CmdBuffer); ret = cdrom->read_track_information(cdb, cmdbuffer);
if (!ret) if (!ret)
{ {
@@ -1353,9 +1353,9 @@ SCSIOut:
return; return;
} }
len = SCSIDevices[id].CmdBuffer[0]; len = cmdbuffer[0];
len <<= 8; len <<= 8;
len |= SCSIDevices[id].CmdBuffer[1]; len |= cmdbuffer[1];
len += 2; len += 2;
} }
else else
@@ -1369,26 +1369,26 @@ SCSIOut:
} }
len = 36; len = 36;
SCSIDevices[id].CmdBuffer[1] = 34; cmdbuffer[1] = 34;
SCSIDevices[id].CmdBuffer[2] = 1; /* track number (LSB) */ cmdbuffer[2] = 1; /* track number (LSB) */
SCSIDevices[id].CmdBuffer[3] = 1; /* session number (LSB) */ cmdbuffer[3] = 1; /* session number (LSB) */
SCSIDevices[id].CmdBuffer[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ cmdbuffer[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */
SCSIDevices[id].CmdBuffer[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ cmdbuffer[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */
SCSIDevices[id].CmdBuffer[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ cmdbuffer[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */
SCSIDevices[id].CmdBuffer[8] = 0; /* track start address is 0 */ cmdbuffer[8] = 0; /* track start address is 0 */
SCSIDevices[id].CmdBuffer[24] = (cdrom->size() >> 24) & 0xff; /* track size */ cmdbuffer[24] = (cdrom->size() >> 24) & 0xff; /* track size */
SCSIDevices[id].CmdBuffer[25] = (cdrom->size() >> 16) & 0xff; /* track size */ cmdbuffer[25] = (cdrom->size() >> 16) & 0xff; /* track size */
SCSIDevices[id].CmdBuffer[26] = (cdrom->size() >> 8) & 0xff; /* track size */ cmdbuffer[26] = (cdrom->size() >> 8) & 0xff; /* track size */
SCSIDevices[id].CmdBuffer[27] = cdrom->size() & 0xff; /* track size */ cmdbuffer[27] = cdrom->size() & 0xff; /* track size */
SCSIDevices[id].CmdBuffer[32] = 0; /* track number (MSB) */ cmdbuffer[32] = 0; /* track number (MSB) */
SCSIDevices[id].CmdBuffer[33] = 0; /* session number (MSB) */ cmdbuffer[33] = 0; /* session number (MSB) */
} }
if (len > max_length) if (len > max_length)
{ {
len = max_length; len = max_length;
SCSIDevices[id].CmdBuffer[0] = ((max_length - 2) >> 8) & 0xff; cmdbuffer[0] = ((max_length - 2) >> 8) & 0xff;
SCSIDevices[id].CmdBuffer[1] = (max_length - 2) & 0xff; cmdbuffer[1] = (max_length - 2) & 0xff;
} }
SCSIPhase = SCSI_PHASE_DATAIN; SCSIPhase = SCSI_PHASE_DATAIN;
@@ -1420,7 +1420,7 @@ SCSIOut:
} }
} }
memset(SCSIDevices[id].CmdBuffer, 0, len > 256 * 512 + 4 ? 256 * 512 + 4 : len); memset(cmdbuffer, 0, len > 256 * 512 + 4 ? 256 * 512 + 4 : len);
switch (cdb[7]) switch (cdb[7])
{ {
@@ -1428,11 +1428,14 @@ SCSIOut:
case 0xff: case 0xff:
if (cdb[1] == 0) if (cdb[1] == 0)
{ {
DVDRet = SCSICDROMReadDVDStructure(cdb[7], cdb, SCSIDevices[id].CmdBuffer); DVDRet = SCSICDROMReadDVDStructure(cdb[7], cdb, cmdbuffer);
if (DVDRet < 0) if (DVDRet < 0)
{ {
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, -DVDRet, 0x00); SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, -DVDRet, 0x00);
SCSICallback[id]=50*SCSI_TIME;
return;
} }
else else
{ {
@@ -1509,14 +1512,14 @@ SCSIOut:
break; break;
case GPCMD_MECHANISM_STATUS: case GPCMD_MECHANISM_STATUS:
SCSIDevices[id].CmdBuffer[0] = 0; cmdbuffer[0] = 0;
SCSIDevices[id].CmdBuffer[1] = 0; cmdbuffer[1] = 0;
SCSIDevices[id].CmdBuffer[2] = 0; cmdbuffer[2] = 0;
SCSIDevices[id].CmdBuffer[3] = 0; cmdbuffer[3] = 0;
SCSIDevices[id].CmdBuffer[4] = 0; cmdbuffer[4] = 0;
SCSIDevices[id].CmdBuffer[5] = 1; cmdbuffer[5] = 1;
SCSIDevices[id].CmdBuffer[6] = 0; cmdbuffer[6] = 0;
SCSIDevices[id].CmdBuffer[7] = 0; cmdbuffer[7] = 0;
SCSIPhase = SCSI_PHASE_DATAIN; SCSIPhase = SCSI_PHASE_DATAIN;
SCSIStatus = SCSI_STATUS_OK; SCSIStatus = SCSI_STATUS_OK;
@@ -1528,7 +1531,7 @@ SCSIOut:
} }
} }
void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen, uint8_t senselen) void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen)
{ {
int read_length = 0; int read_length = 0;
@@ -1539,12 +1542,13 @@ void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen, ui
case GPCMD_READ_12: case GPCMD_READ_12:
case GPCMD_READ_CD_MSF: case GPCMD_READ_CD_MSF:
case GPCMD_READ_CD: case GPCMD_READ_CD:
pclog("Total data length requested: %d\n", datalen); pclog("Total data length requested: %d\n", datalen);
while (datalen > 0) while (datalen > 0)
{ {
read_length = cdrom_read_data(data); //Fill the buffer the data it needs read_length = cdrom_read_data(data); //Fill the buffer the data it needs
if (!read_length) if (!read_length)
{ {
pclog("Invalid read\n");
SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
SCSICallback[id]=50*SCSI_TIME; SCSICallback[id]=50*SCSI_TIME;
@@ -1565,6 +1569,6 @@ void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen, ui
if (SectorLen == 0) if (SectorLen == 0)
break; break;
} }
return; break;
} }
} }