From 3f612ab71a1631136febd185f20bebcda0943e7e Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 20 Jan 2017 23:53:19 +0100 Subject: [PATCH] IDE dword reads and writes reverted to original operation, fixes the last hard disk problems; ATAPI CD-ROM word reads no longer incorrectly discard the upper 16 bits, fixes the CD-ROM problems; Significantly rewrote parts of the AHA-154x and BusLogic emulation, NT 3.1 RTM and MS-DOS drivers now works correctly; The function in cdrom.c to read data blocks from the disc now correctly advances the position of the sector to read in non-passthrough mode, fixes multiblock reads from directly mounted ISO's; Both ATAPI and SCSI now always check for Unit Attention and Not Ready on command execution. --- src/buslogic.c | 757 ++++++++++++++++++++++++++++------------------ src/cdrom-ioctl.c | 14 +- src/cdrom-iso.c | 18 +- src/cdrom.c | 77 +++-- src/cdrom.h | 5 +- src/ide.c | 36 ++- src/ide.h | 1 + src/scsi.c | 18 -- src/scsi.h | 1 - 9 files changed, 551 insertions(+), 376 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index e4a8d8b9a..a1404b934 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -306,7 +306,6 @@ typedef struct __attribute__((packed)) Mailbox32_t } u; } Mailbox32_t; - /////////////////////////////////////////////////////////////////////////////// // // CCB - Buslogic SCSI Command Control Block @@ -511,6 +510,10 @@ typedef struct __attribute__((packed)) Buslogic_t int DmaChannel; int IrqEnabled; int Mbx24bit; + int MailboxOutInterrupts; + int MbiActive[256]; + int DoScan; + int PendingInterrupt; } Buslogic_t; int scsi_model = 1; @@ -518,7 +521,9 @@ int scsi_base = 0x330; int scsi_dma = 6; int scsi_irq = 11; -int buslogic_do_log = 0; +int buslogic_do_log = 1; + +int BuslogicCallback = 0; static void BuslogicStartMailbox(Buslogic_t *Buslogic); @@ -538,9 +543,20 @@ void BuslogicLog(const char *format, ...) static void BuslogicClearInterrupt(Buslogic_t *Buslogic) { - BuslogicLog("Buslogic: Clearing Interrupt 0x%02X\n", Buslogic->Interrupt); + BuslogicLog("Buslogic: Lowering Interrupt 0x%02X\n", Buslogic->Interrupt); Buslogic->Interrupt = 0; + BuslogicLog("Lowering IRQ %i\n", Buslogic->Irq); picintc(1 << Buslogic->Irq); + if (Buslogic->PendingInterrupt) + { + Buslogic->Interrupt = Buslogic->PendingInterrupt; + BuslogicLog("Buslogic: Raising Interrupt 0x%02X (Pending)\n", Buslogic->Interrupt); + if (Buslogic->MailboxOutInterrupts || !(Buslogic->Interrupt & INTR_MBOA)) + { + if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); + } + Buslogic->PendingInterrupt = 0; + } } static void BuslogicLocalRam(Buslogic_t *Buslogic) @@ -568,6 +584,7 @@ static void BuslogicLocalRam(Buslogic_t *Buslogic) static void BuslogicReset(Buslogic_t *Buslogic) { + BuslogicCallback = 0; Buslogic->Status = STAT_IDLE | STAT_INIT; Buslogic->Geometry = 0x80; Buslogic->Command = 0xFF; @@ -578,6 +595,9 @@ static void BuslogicReset(Buslogic_t *Buslogic) Buslogic->ExtendedLUNCCBFormat = 0; Buslogic->MailboxOutPosCur = 0; Buslogic->MailboxInPosCur = 0; + Buslogic->MailboxOutInterrupts = 0; + Buslogic->DoScan = 0; + Buslogic->PendingInterrupt = 0; BuslogicClearInterrupt(Buslogic); @@ -596,32 +616,94 @@ static void BuslogicResetControl(Buslogic_t *Buslogic, uint8_t Reset) static void BuslogicCommandComplete(Buslogic_t *Buslogic) { - Buslogic->Status |= STAT_IDLE; Buslogic->DataReply = 0; + Buslogic->Status |= STAT_IDLE; + if (Buslogic->Command != 0x02) { Buslogic->Status &= ~STAT_DFULL; - Buslogic->Interrupt = INTR_ANY | INTR_HACC; - picint(1 << Buslogic->Irq); + Buslogic->Interrupt = (INTR_ANY | INTR_HACC); + BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); + if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); } Buslogic->Command = 0xFF; Buslogic->CmdParam = 0; } +static uint32_t BuslogicMailboxInRead(Buslogic_t *Buslogic, uint8_t *CompletionCode) +{ + Mailbox32_t TempMailbox32; + Mailbox_t TempMailboxIn; + + uint32_t Incoming = 0; + + Incoming = Buslogic->MailboxInAddr + (Buslogic->MailboxInPosCur * (Buslogic->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); + + if (Buslogic->Mbx24bit) + { + DMAPageRead(Incoming, &TempMailboxIn, sizeof(Mailbox_t)); + *CompletionCode = TempMailboxIn.CmdStatus; + } + else + { + DMAPageRead(Incoming, &TempMailbox32, sizeof(Mailbox32_t)); + *CompletionCode = TempMailbox32.u.in.CompletionCode; + } + + return Incoming; +} + +static void BuslogicMailboxInAdvance(Buslogic_t *Buslogic) +{ + Buslogic->MailboxInPosCur = (Buslogic->MailboxInPosCur + 1) % Buslogic->MailboxCount; +} + static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *CmdBlock, uint8_t HostStatus, uint8_t TargetStatus, uint8_t MailboxCompletionCode) { Mailbox32_t Mailbox32; Mailbox_t MailboxIn; + + Mailbox32_t TempMailbox32; + Mailbox_t TempMailboxIn; + + uint32_t Incoming = 0; + uint32_t i = 0; + + uint8_t CompletionCode = 0; Mailbox32.CCBPointer = CCBPointer; Mailbox32.u.in.HostStatus = HostStatus; Mailbox32.u.in.TargetStatus = TargetStatus; Mailbox32.u.in.CompletionCode = MailboxCompletionCode; - - uint32_t Incoming = Buslogic->MailboxInAddr + (Buslogic->MailboxInPosCur * (Buslogic->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); + + Incoming = 0; + + if (!Buslogic->StrictRoundRobinMode) + { + uint8_t MailboxCur = Buslogic->MailboxInPosCur; + + /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ + do + { + /* Fetch mailbox from guest memory. */ + Incoming = BuslogicMailboxInRead(Buslogic, &CompletionCode); + + /* Check the next mailbox. */ + BuslogicMailboxInAdvance(Buslogic); + } while ((CompletionCode != MBI_FREE) && (MailboxCur != Buslogic->MailboxInPosCur)); + } + else + { + Incoming = BuslogicMailboxInRead(Buslogic, &CompletionCode); + } + + if (CompletionCode != MBI_FREE) + { + return; + } if (MailboxCompletionCode != MBI_NOT_FOUND) { @@ -629,12 +711,16 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C CmdBlock->common.TargetStatus = TargetStatus; //Rewrite the CCB up to the CDB. - if (CmdBlock->common.TargetStatus != 0x02) + if ((CmdBlock->common.TargetStatus != 0x02) && (CCBPointer != 0)) { BuslogicLog("CCB rewritten to the CDB (pointer %08X, length %i)\n", CCBPointer, offsetof(CCBC, Cdb)); DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); } } + else + { + BuslogicLog("Mailbox not found!\n"); + } BuslogicLog("Host Status 0x%02X, Target Status 0x%02X\n", HostStatus, TargetStatus); @@ -645,20 +731,36 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C BuslogicLog("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", MailboxIn.CmdStatus, ADDR_TO_U32(MailboxIn.CCBPointer)); DMAPageWrite(Incoming, &MailboxIn, sizeof(Mailbox_t)); + BuslogicLog("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); } else { BuslogicLog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); - DMAPageWrite(Incoming, &Mailbox32, sizeof(Mailbox32_t)); + if (Incoming != 0) + { + DMAPageWrite(Incoming, &Mailbox32, sizeof(Mailbox32_t)); + BuslogicLog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); + } + } + + /* Advance to the next mailbox. */ + if (Buslogic->StrictRoundRobinMode) + { + BuslogicMailboxInAdvance(Buslogic); + } + + if (Buslogic->Interrupt & INTR_HACC) + { + BuslogicLog("Pending IRQ\n"); + Buslogic->PendingInterrupt = INTR_MBIF | INTR_ANY; + } + else + { + Buslogic->Interrupt = INTR_MBIF | INTR_ANY; + BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); + if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); } - - Buslogic->MailboxInPosCur++; - if (Buslogic->MailboxInPosCur > Buslogic->MailboxCount) - Buslogic->MailboxInPosCur = 0; - - Buslogic->Interrupt = INTR_MBIF | INTR_ANY; - picint(1 << Buslogic->Irq); } static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) @@ -688,6 +790,8 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi uint32_t sg_buffer_pos = 0; uint32_t DataPointer, DataLength; + uint32_t ScatterGatherEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + if (Is24bit) { DataPointer = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataPointer); @@ -699,17 +803,9 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi DataLength = BuslogicRequests->CmdBlock.new.DataLength; } - /* if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) - DataLength = 0; */ - - if ((BuslogicRequests->CmdBlock.common.Cdb[0] != GPCMD_MODE_SELECT_6) && (BuslogicRequests->CmdBlock.common.Cdb[0] != GPCMD_MODE_SELECT_10)) - { - return; - } - BuslogicLog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); - if (DataLength && BuslogicRequests->CmdBlock.common.ControlByte != 0x03) + if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && DataLength) { if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) @@ -717,7 +813,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi uint32_t ScatterGatherRead; uint32_t ScatterEntry; SGE32 ScatterGatherBuffer[MAX_SG_DESCRIPTORS]; - uint32_t ScatterGatherLeft = DataLength / (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + uint32_t ScatterGatherLeft = DataLength / ScatterGatherEntryLength; uint32_t ScatterGatherAddrCurrent = DataPointer; uint32_t DataToTransfer = 0; @@ -733,12 +829,16 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi for (ScatterEntry = 0; ScatterEntry < ScatterGatherRead; ScatterEntry++) { uint32_t Address; - + + BuslogicLog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); + Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer += ScatterGatherBuffer[ScatterEntry].Segment; + + BuslogicLog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); } - ScatterGatherAddrCurrent += ScatterGatherRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + ScatterGatherAddrCurrent += ScatterGatherRead * ScatterGatherEntryLength; } while (ScatterGatherLeft > 0); BuslogicLog("Data to transfer (S/G) %d\n", DataToTransfer); @@ -749,7 +849,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi //checking its length, so do this procedure for both no read/write commands. if (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT || BuslogicRequests->CmdBlock.common.ControlByte == 0x00) { - ScatterGatherLeft = DataLength / (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + ScatterGatherLeft = DataLength / ScatterGatherEntryLength; ScatterGatherAddrCurrent = DataPointer; do @@ -764,10 +864,14 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi for (ScatterEntry = 0; ScatterEntry < ScatterGatherRead; ScatterEntry++) { uint32_t Address; - + + BuslogicLog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); + Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; + BuslogicLog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); + DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); sg_buffer_pos += DataToTransfer; } @@ -819,42 +923,40 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) DataLength = BuslogicRequests->CmdBlock.new.DataLength; } - if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) + /* if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) { DataLength = SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength; - } + } */ if ((DataLength != 0) && (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) { BuslogicLog("Data length not 0 with TEST UNIT READY: %i (%i)\n", DataLength, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength); } - /* if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) - DataLength = 0; */ + if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) + { + DataLength = 0; + } BuslogicLog("Data Buffer read: length %d, pointer 0x%04X\n", DataLength, DataPointer); //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. - if (DataLength > 0 && (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN || - BuslogicRequests->CmdBlock.common.ControlByte == 0x00) && BuslogicRequests->CmdBlock.common.ControlByte != 0x03) + if ((DataLength > 0) && + ((BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || + (BuslogicRequests->CmdBlock.common.ControlByte == 0x00))) { - if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || - BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) + if ((BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) || + (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { uint32_t ScatterGatherRead; uint32_t ScatterEntry; SGE32 ScatterGatherBuffer[MAX_SG_DESCRIPTORS]; - uint32_t ScatterGatherReqSize = (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); - uint32_t ScatterGatherLeft = DataLength / ScatterGatherReqSize; - uint32_t ScatterGatherLength = (ScatterGatherLeft * ScatterGatherReqSize); + uint32_t ScatterGatherEntrySize = (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); + uint32_t ScatterGatherLeft = DataLength / ScatterGatherEntrySize; + // uint32_t ScatterGatherLength = (ScatterGatherLeft * ScatterGatherEntrySize); uint32_t ScatterGatherAddrCurrent = DataPointer; - if (DataLength > ScatterGatherLength) - { - ScatterGatherLeft++; - } - do { ScatterGatherRead = (ScatterGatherLeft < ELEMENTS(ScatterGatherBuffer)) @@ -868,36 +970,57 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) { uint32_t Address; uint32_t DataToTransfer; + + BuslogicLog("BusLogic S/G: ScatterEntry=%u\n", ScatterEntry); Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; + BuslogicLog("BusLogic S/G: Writing %i bytes at %08X\n", DataToTransfer, Address); + DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); sg_buffer_pos += DataToTransfer; } - ScatterGatherAddrCurrent += ScatterGatherRead * (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); + ScatterGatherAddrCurrent += (ScatterGatherRead * ScatterGatherEntrySize); } while (ScatterGatherLeft > 0); } else if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { uint32_t Address = DataPointer; - if (DataLength > 0) - { - if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) - { - DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength); - } - else - { - DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, DataLength); - } - } + + BuslogicLog("BusLogic DMA: Writing %i bytes at %08X\n", DataLength, Address); + DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, DataLength); } } - SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = 0; + if ((BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) || (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) + { + uint32_t Residual; + + /* Should be 0 when scatter/gather? */ + if (DataLength >= SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) + { + Residual = BuslogicGetDataLength(BuslogicRequests); + Residual -= SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength; + } + else + { + Residual = 0; + } + + if (BuslogicRequests->Is24bit) + { + U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, Residual); + BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); + } + else + { + BuslogicRequests->CmdBlock.new.DataLength = Residual; + BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); + } + } } uint8_t BuslogicRead(uint16_t Port, void *p) @@ -942,7 +1065,7 @@ uint8_t BuslogicRead(uint16_t Port, void *p) break; } - BuslogicLog("Buslogic: Read Port 0x%02X, Returned Value %02X\n", Port, Temp); + // BuslogicLog("Buslogic: Read Port 0x%02X, Returned Value %02X\n", Port, Temp); return Temp; } @@ -980,7 +1103,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic_t *Buslogic = (Buslogic_t *)p; BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val); + // BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val); switch (Port & 3) { @@ -999,16 +1122,9 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 1: - if ((Val == 0x02) && (Buslogic->Command == 0xFF)) + if (!(Buslogic->Status & STAT_IDLE) && (Buslogic->Command == 0xFF) && (Val != 0x02) && (Val != 0x05)) { - for (i = 0; i < CDROM_NUM; i++) - { - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun)) - { - SCSICallback[cdrom_drives[i].scsi_device_id][cdrom_drives[i].scsi_device_lun] = 1; - } - } - break; + break; /* Any command other than 02 and 05 can only be executed when the IDLE bit is set. */ } if (Buslogic->Command == 0xFF) @@ -1021,6 +1137,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) switch (Buslogic->Command) { case 0x00: + case 0x02: case 0x04: case 0x0A: case 0x0B: @@ -1030,6 +1147,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->CmdParamLeft = 0; break; + case 0x05: case 0x07: case 0x08: case 0x09: @@ -1066,6 +1184,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x81: + BuslogicLog("Command 0x81 on %s\n", scsi_model ? "BusLogic" : "Adaptec"); Buslogic->CmdParamLeft = scsi_model ? sizeof(MailboxInitExtended_t) : 0; break; @@ -1112,15 +1231,49 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->DataReplyLeft = 0; } break; + + case 0x02: + if (Buslogic->Status & STAT_INIT) + { + Buslogic->Status |= STAT_INVCMD; + } + else + { + if (!BuslogicCallback) + { + BuslogicLog("SCSI started\n"); + BuslogicCallback = 1; + } + else + { + BuslogicLog("SCSI reactivated\n"); + } + Buslogic->DoScan = 1; + } + Buslogic->DataReplyLeft = 0; + break; case 0x04: Buslogic->DataBuf[0] = 0x41; Buslogic->DataBuf[1] = scsi_model ? 0x41 : 0x30; - Buslogic->DataBuf[2] = '5'; - Buslogic->DataBuf[3] = '0'; + Buslogic->DataBuf[2] = scsi_model ? '5' : '3'; + Buslogic->DataBuf[3] = scsi_model ? '0' : '1'; Buslogic->DataReplyLeft = 4; break; + case 0x05: + if (Buslogic->CmdBuf[0] <= 1) + { + Buslogic->MailboxOutInterrupts = Buslogic->CmdBuf[0]; + BuslogicLog("Mailbox out interrupts: %s\n", Buslogic->MailboxOutInterrupts ? "ON" : "OFF"); + } + else + { + Buslogic->Status |= STAT_INVCMD; + } + Buslogic->DataReplyLeft = 0; + break; + case 0x06: Buslogic->DataReplyLeft = 0; break; @@ -1226,6 +1379,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Address.mid = Buslogic->CmdBuf[1]; Address.lo = Buslogic->CmdBuf[2]; FIFOBuf = ADDR_TO_U32(Address); + BuslogicLog("Buslogic FIFO: Writing 64 bytes at %08X\n", FIFOBuf); DMAPageWrite(FIFOBuf, &Buslogic->LocalRam.u8View[64], 64); } break; @@ -1265,6 +1419,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->IrqEnabled = 0; else Buslogic->IrqEnabled = 1; + BuslogicLog("Lowering IRQ %i\n", Buslogic->Irq); picintc(1 << Buslogic->Irq); break; @@ -1408,6 +1563,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) } break; + default: case 0x22: //undocumented case 0x28: //only for the Adaptec 154xC series case 0x29: //only for the Adaptec 154xC series @@ -1449,14 +1605,6 @@ static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) return RequestSenseLength; } -static void BuslogicSenseBufferAllocate(BuslogicRequests_t *BuslogicRequests) -{ - uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength); - - if (SenseLength) - BuslogicRequests->RequestSenseBuffer = (uint8_t *)malloc(SenseLength); -} - static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Copy) { uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength); @@ -1480,14 +1628,85 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co } BuslogicLog("Request Sense address: %02X\n", SenseBufferAddress); - - DMAPageWrite(SenseBufferAddress, cdrom[cdrom_id].sense, SenseLength); + + if (SenseBufferAddress) + { + BuslogicLog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress); + DMAPageWrite(SenseBufferAddress, cdrom[cdrom_id].sense, SenseLength); + } } - //Free the sense buffer when needed. - free(BuslogicRequests->RequestSenseBuffer); } -static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Mailbox32_t *Mailbox32) +static void BuslogicCDROMCommand(Buslogic_t *Buslogic, uint8_t Id, uint8_t Lun, uint8_t cdrom_id) +{ + BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; + uint8_t cdrom_phase; + + uint32_t temp = 0; + + uint8_t temp_cdb[12]; + uint32_t i; + + BuslogicLog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", Id, Lun, cdrom_id); + + 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]); + } + + memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len); + if (BuslogicRequests->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len) + { + memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, BuslogicRequests->CmdBlock.common.CdbLength); + } + else + { + memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len); + } + + cdrom[cdrom_id].request_length = temp_cdb[1]; /* Since that field in the cdrom struct is never used when the bus type is SCSI, let's use it for this scope. */ + + if (BuslogicRequests->CmdBlock.common.CdbLength != 12) + { + temp_cdb[1] &= 0x1f; /* Make sure the LUN field of the temporary CDB is always 0, otherwise Daemon Tools drives will misehave when a command is passed through to them. */ + } + + memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); + + //Finally, execute the SCSI command immediately and get the transfer length. + + SCSIPhase = SCSI_PHASE_COMMAND; + SCSIDevices[Id][Lun].InitLength = 0; + cdrom_command(cdrom_id, temp_cdb); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + if (SCSIStatus == SCSI_STATUS_OK) + { + cdrom_phase = cdrom_atapi_phase_to_scsi(cdrom_id); + if (cdrom_phase == 2) + { + /* Command completed - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + else + { + /* Command first phase complete - call the callback to execute the second phase. */ + cdrom_phase_callback(cdrom_id); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + /* Command second phase complete - call the callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + } + else + { + /* Error (Check Condition) - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + + BuslogicLog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]); +} + +static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Mailbox32_t *Mailbox32) { BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; uint8_t Id, Lun; @@ -1495,9 +1714,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, uint8_t cdrom_id; uint8_t cdrom_phase; - uint32_t temp = 0; - - uint8_t temp_cdb[12]; + uint8_t last_id = scsi_model ? 15 : 7; //Fetch data from the Command Control Block. DMAPageRead(CCBPointer, &BuslogicRequests->CmdBlock, sizeof(CCB32)); @@ -1507,171 +1724,69 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Id = BuslogicRequests->TargetID; Lun = BuslogicRequests->LUN; + + if ((Id > last_id) || (Lun > 7)) + { + BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); + return 1; + } BuslogicLog("Scanning SCSI Target ID %i\n", Id); - - //Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. - if (buslogic_scsi_drive_is_cdrom(Id, Lun)) + + cdrom_id = scsi_cdrom_drives[Id][Lun]; + + BuslogicRequests->CCBPointer = CCBPointer; + BuslogicRequests->Is24bit = Buslogic->Mbx24bit; + + SCSIStatus = SCSI_STATUS_OK; + + BuslogicDataBufferAllocate(BuslogicRequests, BuslogicRequests->Is24bit); + + if (!buslogic_scsi_drive_is_cdrom(Id, Lun)) { - cdrom_id = scsi_cdrom_drives[Id][Lun]; + BuslogicLog("SCSI Target ID %i and LUN %i have no device attached\n", Id, Lun); - BuslogicLog("SCSI Target ID %i detected and working\n", Id); + BuslogicDataBufferFree(BuslogicRequests); - BuslogicRequests->CCBPointer = CCBPointer; - BuslogicRequests->Is24bit = Buslogic->Mbx24bit; + BuslogicSenseBufferFree(BuslogicRequests, 0); - if (Mailbox32->u.out.ActionCode == MBO_START) - { - BuslogicSenseBufferAllocate(BuslogicRequests); - - BuslogicDataBufferAllocate(BuslogicRequests, BuslogicRequests->Is24bit); - - 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]); - - memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len); - if (BuslogicRequests->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len) - { - memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, BuslogicRequests->CmdBlock.common.CdbLength); - } - else - { - memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len); - } - - if (BuslogicRequests->CmdBlock.common.CdbLength != 12) - { - cdrom[cdrom_id].request_length = temp_cdb[1]; /* Since that field in the cdrom struct is never used when the bus type is SCSI, let's use it for this scope. */ - temp_cdb[1] &= 0x1f; /* Make sure the LUN field of the temporary CDB is always 0, otherwise Daemon Tools drives will misehave when a command is passed through to them. */ - } - - 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); - - //This not ready/unit attention stuff below is only for the Buslogic! - //The Adaptec one is in scsi_cdrom.c. - - if (!cdrom_drives[cdrom_id].check_on_execution) - { - if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND)) - { - if (!cdrom_pre_execution_check(cdrom_id, temp_cdb)) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSICallback[Id][Lun]=50*SCSI_TIME; - SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = 0; - if (BuslogicRequests->RequestSenseBuffer) - BuslogicSenseBufferFree(BuslogicRequests, 1); - BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); - return; - } - } - } - - memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); - - //Finally, execute the SCSI command immediately and get the transfer length. - - SCSIPhase = SCSI_PHASE_COMMAND; - SCSIDevices[Id][Lun].InitLength = 0; - cdrom_command(cdrom_id, temp_cdb); - SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); - if (SCSIStatus == SCSI_STATUS_OK) - { - cdrom_phase = cdrom_atapi_phase_to_scsi(cdrom_id); - if (cdrom_phase == 2) - { - /* Command completed - call the phase callback to complete the command. */ - cdrom_phase_callback(cdrom_id); - } - else - { - /* Command first phase complete - call the callback to execute the second phase. */ - cdrom_phase_callback(cdrom_id); - SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); - /* Command second phase complete - call the callback to complete the command. */ - cdrom_phase_callback(cdrom_id); - } - } - else - { - /* Error (Check Condition) - call the phase callback to complete the command. */ - cdrom_phase_callback(cdrom_id); - } - SCSICallback[Id][Lun] = cdrom[cdrom_id].callback; - - if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (SCSIDevices[Id][Lun].InitLength != 0)) - { - BuslogicDataBufferFree(BuslogicRequests); - } - - if (BuslogicRequests->RequestSenseBuffer) - BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); - } - else - { - BuslogicLog("Mailbox32->u.out.ActionCode = %02X\n", Mailbox32->u.out.ActionCode); - SCSICallback[Id][Lun] = 50 * SCSI_TIME; - } - - BuslogicLog("Request complete\n"); - - if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) - { - temp = BuslogicGetDataLength(BuslogicRequests); - temp -= SCSIDevices[Id][Lun].InitLength; - - if (BuslogicRequests->Is24bit) - { - U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, temp); - BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); - } - else - { - BuslogicRequests->CmdBlock.new.DataLength = temp; - BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); - } - } - else if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) - { - if (BuslogicRequests->Is24bit) - { - U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, 0); - BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); - } - else - { - BuslogicRequests->CmdBlock.new.DataLength = 0; - BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); - } - } - - if (SCSIStatus == SCSI_STATUS_OK) - { - BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, - MBI_SUCCESS); - } - else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) - { - BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, - MBI_ERROR); - } + BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); } else { - BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); + BuslogicLog("SCSI Target ID %i and LUN %i detected and working\n", Id, Lun); + + 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 (BuslogicRequests->CmdBlock.common.ControlByte > 0x03) + { + BuslogicLog("Invalid control byte: %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); + } + + BuslogicCDROMCommand(Buslogic, Id, Lun, cdrom_id); + + BuslogicDataBufferFree(BuslogicRequests); - // if (Mailbox32->u.out.ActionCode == MBO_START && Lun == 0) - if (Mailbox32->u.out.ActionCode == MBO_START && Lun <= 7) - BuslogicStartMailbox(Buslogic); + BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); + + BuslogicLog("Request complete\n"); + + if (SCSIStatus == SCSI_STATUS_OK) + { + BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + } + else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) + { + BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); + } } + + return 1; } -static void BuslogicSCSIRequestAbort(Buslogic_t *Buslogic, uint32_t CCBPointer) +static int BuslogicSCSIRequestAbort(Buslogic_t *Buslogic, uint32_t CCBPointer) { BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; CCBU CmdBlock; @@ -1681,6 +1796,8 @@ static void BuslogicSCSIRequestAbort(Buslogic_t *Buslogic, uint32_t CCBPointer) //Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); + + return 1; } static uint32_t BuslogicMailboxOut(Buslogic_t *Buslogic, Mailbox32_t *Mailbox32) @@ -1707,70 +1824,127 @@ static uint32_t BuslogicMailboxOut(Buslogic_t *Buslogic, Mailbox32_t *Mailbox32) return Outgoing; } -static void BuslogicStartMailbox(Buslogic_t *Buslogic) -{ +static void BuslogicMailboxOutAdvance(Buslogic_t *Buslogic) +{ + Buslogic->MailboxOutPosCur = (Buslogic->MailboxOutPosCur + 1) % Buslogic->MailboxCount; +} + +static int BuslogicProcessMailbox(Buslogic_t *Buslogic) +{ Mailbox32_t Mailbox32; Mailbox_t MailboxOut; uint32_t Outgoing; - uint8_t MailboxOutCur = Buslogic->MailboxOutPosCur; - - do + uint8_t CmdStatus = MBO_FREE; + uint32_t CodeOffset = 0; + + int old_irq_enabled = Buslogic->IrqEnabled; + + BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; + + int ret = 0; + + CodeOffset = Buslogic->Mbx24bit ? offsetof(Mailbox_t, CmdStatus) : offsetof(Mailbox32_t, u.out.ActionCode); + + if (!Buslogic->StrictRoundRobinMode) + { + uint8_t MailboxCur = Buslogic->MailboxOutPosCur; + + /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ + do + { + /* Fetch mailbox from guest memory. */ + Outgoing = BuslogicMailboxOut(Buslogic, &Mailbox32); + + /* Check the next mailbox. */ + BuslogicMailboxOutAdvance(Buslogic); + } while ((Mailbox32.u.out.ActionCode == MBO_FREE) && (MailboxCur != Buslogic->MailboxOutPosCur)); + } + else { Outgoing = BuslogicMailboxOut(Buslogic, &Mailbox32); - Buslogic->MailboxOutPosCur = (Buslogic->MailboxOutPosCur + 1) % Buslogic->MailboxCount; - } while (Mailbox32.u.out.ActionCode == MBO_FREE && MailboxOutCur != Buslogic->MailboxOutPosCur); + } - uint8_t CmdStatus = MBO_FREE; - uint32_t CodeOffset = Buslogic->Mbx24bit ? offsetof(Mailbox_t, CmdStatus) : offsetof(Mailbox32_t, u.out.ActionCode); + /* Check if the mailbox is actually loaded. */ + if (Mailbox32.u.out.ActionCode == MBO_FREE) + { + BuslogicLog("No loaded mailbox left\n"); - DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, sizeof(CmdStatus)); - - if (Mailbox32.u.out.ActionCode == MBO_START || Mailbox32.u.out.ActionCode == MBO_FREE) + if (Buslogic->MailboxOutInterrupts) + { + if (Buslogic->Interrupt & INTR_HACC) + { + BuslogicLog("Pending IRQ\n"); + Buslogic->PendingInterrupt = INTR_MBOA | INTR_ANY; + } + else + { + BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); + Buslogic->Interrupt = INTR_MBOA | INTR_ANY; + if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); + } + } + + return 0; + } + + /* We got the mailbox, mark it as free in the guest. */ + if (Mailbox32.u.out.ActionCode != MBO_FREE) + { + BuslogicLog("BuslogicStartMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); + DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, sizeof(CmdStatus)); + } + + if ((Mailbox32.u.out.ActionCode == MBO_START) || (Mailbox32.u.out.ActionCode == MBO_FREE)) { BuslogicLog("Start Mailbox Command\n"); - BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer, &Mailbox32); + ret = BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer, &Mailbox32); } else if (Mailbox32.u.out.ActionCode == MBO_ABORT) { BuslogicLog("Abort Mailbox Command\n"); - BuslogicSCSIRequestAbort(Buslogic, Mailbox32.CCBPointer); + ret = BuslogicSCSIRequestAbort(Buslogic, Mailbox32.CCBPointer); } + else + { + BuslogicLog("Invalid action code: %02X\n", Mailbox32.u.out.ActionCode); + ret = 0; + } + + /* Advance to the next mailbox. */ + if (Buslogic->StrictRoundRobinMode) + { + BuslogicMailboxOutAdvance(Buslogic); + } + + return ret; } -void BuslogicCommandCallback(int id, int lun, void *p) +void BuslogicCommandCallback(void *p) { Buslogic_t *Buslogic = (Buslogic_t *)p; + + int ret = 0; + int i = 0; + + // BuslogicLog("BusLogic Callback!\n"); - SCSICallback[id][lun] = 0; if (Buslogic->MailboxCount) { - BuslogicStartMailbox(Buslogic); + ret = BuslogicProcessMailbox(Buslogic); + + BuslogicCallback += 50 * SCSI_TIME; + } + else + { + fatal("Callback active with mailbox count 0!\n"); } -} - -void BuslogicCommandCallback0(void *p) -{ - BuslogicCommandCallback(cdrom_drives[0].scsi_device_id, cdrom_drives[0].scsi_device_lun, p); -} - -void BuslogicCommandCallback1(void *p) -{ - BuslogicCommandCallback(cdrom_drives[1].scsi_device_id, cdrom_drives[1].scsi_device_lun, p); -} - -void BuslogicCommandCallback2(void *p) -{ - BuslogicCommandCallback(cdrom_drives[2].scsi_device_id, cdrom_drives[2].scsi_device_lun, p); -} - -void BuslogicCommandCallback3(void *p) -{ - BuslogicCommandCallback(cdrom_drives[3].scsi_device_id, cdrom_drives[3].scsi_device_lun, p); } void *BuslogicInit() { + int i = 0; + Buslogic_t *Buslogic = malloc(sizeof(Buslogic_t)); memset(Buslogic, 0, sizeof(Buslogic_t)); @@ -1782,26 +1956,15 @@ void *BuslogicInit() BuslogicLog("Building CD-ROM map...\n"); build_scsi_cdrom_map(); - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id, cdrom_drives[0].scsi_device_lun)) + for (i = 0; i < CDROM_NUM; i++) { - SCSIDevices[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback0, &SCSICallback[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun], &SCSICallback[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun], Buslogic); - } - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[1].scsi_device_id, cdrom_drives[1].scsi_device_lun)) - { - SCSIDevices[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback1, &SCSICallback[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun], &SCSICallback[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun], Buslogic); - } - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[2].scsi_device_id, cdrom_drives[2].scsi_device_lun)) - { - SCSIDevices[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback2, &SCSICallback[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun], &SCSICallback[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun], Buslogic); - } - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[3].scsi_device_id, cdrom_drives[3].scsi_device_lun)) - { - SCSIDevices[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback3, &SCSICallback[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun], &SCSICallback[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun], Buslogic); + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun)) + { + SCSIDevices[cdrom_drives[i].scsi_device_id][cdrom_drives[i].scsi_device_lun].LunType == SCSI_CDROM; + } } + + timer_add(BuslogicCommandCallback, &BuslogicCallback, &BuslogicCallback, Buslogic); BuslogicLog("Buslogic on port 0x%04X\n", scsi_base); @@ -1826,4 +1989,4 @@ device_t BuslogicDevice = NULL, NULL, NULL -}; \ No newline at end of file +}; diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 7fc61eeb3..490d4ab45 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -779,6 +779,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t int transferred_blocks = 0; int temp_len = 0; + int chunk = 0; if (cdb[0] == 0x43) { @@ -791,13 +792,14 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t memcpy(cdb, in_cdb, 12); temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0); + *len = 0; if (temp_block_length != -1) { if (temp_block_length > 65534) { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is bigger than 65534, splitting the transfer...\n", id, temp_block_length); block_length = temp_block_length / cdrom[id].requested_blocks; blocks_at_once = 32768 / block_length; + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is bigger than 65534, splitting the transfer into chunks of %i blocks...\n", id, temp_block_length, blocks_at_once); buffer_pos = 0; temp_pos = cdrom[id].sector_pos; @@ -806,12 +808,15 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t temp_len = 0; split_block_read_iterate: - if (temp_requested_blocks < blocks_at_once) + chunk = (cdrom[id].requested_blocks - transferred_blocks); + if (chunk < blocks_at_once) { - cdrom_ioctl[id].actual_requested_blocks = temp_requested_blocks; + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is less than a complete split block\n", id, chunk); + cdrom_ioctl[id].actual_requested_blocks = chunk; } else { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is more or equal than a complete split block\n", id, chunk); cdrom_ioctl[id].actual_requested_blocks = blocks_at_once; } cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring %i blocks...\n", id, cdrom_ioctl[id].actual_requested_blocks); @@ -819,8 +824,9 @@ split_block_read_iterate: ret = SCSICommand(id, cdb, buf + buffer_pos, &temp_len, 0); *len += temp_len; transferred_blocks += cdrom_ioctl[id].actual_requested_blocks; - if (ret && (transferred_blocks >= cdrom[id].requested_blocks)) + if (ret && (transferred_blocks < cdrom[id].requested_blocks)) { + /* Return value was successful and there are still more blocks left to transfer. */ temp_pos += cdrom_ioctl[id].actual_requested_blocks; buffer_pos += (cdrom_ioctl[id].actual_requested_blocks * block_length); goto split_block_read_iterate; diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c index bb3d7c361..241e1e3dd 100644 --- a/src/cdrom-iso.c +++ b/src/cdrom-iso.c @@ -3,6 +3,8 @@ */ /*ISO CD-ROM support*/ +#include + #include "ibm.h" #include "cdrom.h" #include "cdrom-iso.h" @@ -10,12 +12,12 @@ static CDROM iso_cdrom; -int cdrom_iso_do_log = 1; +int cdrom_iso_do_log = 0; void cdrom_iso_log(const char *format, ...) { #ifdef ENABLE_CDROM_ISO_LOG - if (cdrom_do_log) + if (cdrom_iso_do_log) { va_list ap; va_start(ap, format); @@ -273,12 +275,14 @@ static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf if (cdrom_sector_flags & 0x80) /* Sync */ { + cdrom_iso_log("CD-ROM %i: Sync\n", id); memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.sync, 12); cdrom_sector_size += 12; temp_b += 12; } if (cdrom_sector_flags & 0x20) /* Header */ { + cdrom_iso_log("CD-ROM %i: Header\n", id); memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.header, 4); cdrom_sector_size += 4; temp_b += 4; @@ -289,6 +293,7 @@ static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf { if (!(cdrom_sector_flags & 0x10)) /* No user data */ { + cdrom_iso_log("CD-ROM %i: Sub-header\n", id); memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 8); cdrom_sector_size += 8; temp_b += 8; @@ -296,12 +301,14 @@ static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf } if (cdrom_sector_flags & 0x10) /* User data */ { + cdrom_iso_log("CD-ROM %i: User data\n", id); memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 2048); cdrom_sector_size += 2048; temp_b += 2048; } if (cdrom_sector_flags & 0x08) /* EDC/ECC */ { + cdrom_iso_log("CD-ROM %i: EDC/ECC\n", id); memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.ecc, 288); cdrom_sector_size += 288; temp_b += 288; @@ -312,33 +319,36 @@ static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf if ((cdrom_sector_flags & 0x06) == 0x02) { /* Add error flags. */ + cdrom_iso_log("CD-ROM %i: Error flags\n", id); memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 294); cdrom_sector_size += 294; } else if ((cdrom_sector_flags & 0x06) == 0x04) { /* Add error flags. */ + cdrom_iso_log("CD-ROM %i: Full error flags\n", id); memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 296); cdrom_sector_size += 296; } if ((cdrom_sector_flags & 0x700) == 0x100) { + cdrom_iso_log("CD-ROM %i: Raw subchannel data\n", id); memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_raw, 96); cdrom_sector_size += 96; } else if ((cdrom_sector_flags & 0x700) == 0x200) { + cdrom_iso_log("CD-ROM %i: Q subchannel data\n", id); memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_q, 16); cdrom_sector_size += 16; } else if ((cdrom_sector_flags & 0x700) == 0x400) { + cdrom_iso_log("CD-ROM %i: R/W subchannel data\n", id); memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_rw, 96); cdrom_sector_size += 96; } - - memcpy(buffer, b, cdrom_sector_size); *len = cdrom_sector_size; diff --git a/src/cdrom.c b/src/cdrom.c index 0aad0daf8..e7cb9c63f 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -330,12 +330,10 @@ void cdrom_init(int id, int cdb_len_setting, int bus_type) if (!cdrom_drives[id].bus_type) { cdrom_set_signature(id); - cdrom_drives[id].check_on_execution = 1; cdrom_drives[id].max_blocks_at_once = 1; } else { - cdrom_drives[id].check_on_execution = scsi_model ? 0 : 1; cdrom_drives[id].max_blocks_at_once = 85; } cdrom[id].status = READY_STAT | DSC_STAT; @@ -881,12 +879,12 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { if (cdrom_current_mode(id) == 2) { - if (cdrom_drives[id].bus_type) - { - SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len; - } if (direction == 0) { + if (cdrom_drives[id].bus_type) + { + SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len; + } cdrom_command_read_dma(id); } else @@ -1121,6 +1119,8 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) int i = 0; int temp_len = 0; + int last_valid_data_pos = 0; + if (cdrom_drives[id].handler->pass_through) { cdsize = cdrom_drives[id].handler->size(id); @@ -1156,7 +1156,9 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) for (i = 0; i < cdrom[id].requested_blocks; i++) { - ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + cdrom[id].data_pos, cdrom[id].sector_pos, msf, type, flags, &temp_len); + ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + cdrom[id].data_pos, cdrom[id].sector_pos + i, msf, type, flags, &temp_len); + + last_valid_data_pos = cdrom[id].data_pos; cdrom[id].data_pos += temp_len; cdrom[id].old_len += temp_len; @@ -1170,7 +1172,7 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) } } - cdrom_log("CD-ROM %i: Data from raw sector read: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[cdrom[id].data_pos + 0], cdbufferb[cdrom[id].data_pos + 1], cdbufferb[cdrom[id].data_pos + 2], cdbufferb[cdrom[id].data_pos + 3], cdbufferb[cdrom[id].data_pos + 4], cdbufferb[cdrom[id].data_pos + 5], cdbufferb[cdrom[id].data_pos + 6], cdbufferb[cdrom[id].data_pos + 7]); + cdrom_log("CD-ROM %i: Data from raw sector read: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[last_valid_data_pos + 0], cdbufferb[last_valid_data_pos + 1], cdbufferb[last_valid_data_pos + 2], cdbufferb[last_valid_data_pos + 3], cdbufferb[last_valid_data_pos + 4], cdbufferb[last_valid_data_pos + 5], cdbufferb[last_valid_data_pos + 6], cdbufferb[last_valid_data_pos + 7]); } return 1; @@ -1616,12 +1618,9 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom[id].sector_len = 0; /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (cdrom_drives[id].check_on_execution) + if (cdrom_pre_execution_check(id, cdb) == 0) { - if (cdrom_pre_execution_check(id, cdb) == 0) - { - return; - } + return; } cdrom[id].prev_status = cdrom[id].cd_status; @@ -2645,7 +2644,7 @@ int cdrom_mode_select_return(uint8_t id, int ret) } } -int cdrom_phase_callback(uint8_t id); +void cdrom_phase_callback(uint8_t id); int cdrom_read_from_ide_dma(uint8_t channel) { @@ -2799,58 +2798,72 @@ int cdrom_write_to_dma(uint8_t id) return 1; } +void cdrom_irq_raise(uint8_t id) +{ + if (!cdrom_drives[id].bus_type) + { + ide_irq_raise(&(ide_drives[cdrom_drives[id].ide_channel])); + } +} + /* If the result is 1, issue an IRQ, otherwise not. */ -int cdrom_phase_callback(uint8_t id) +void cdrom_phase_callback(uint8_t id) { switch(cdrom[id].packet_status) { case CDROM_PHASE_IDLE: - // cdrom_log("CD-ROM %i: CDROM_PHASE_IDLE\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_IDLE\n", id); cdrom[id].pos=0; cdrom[id].phase = 1; cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); - return 0; + return; case CDROM_PHASE_COMMAND: - // cdrom_log("CD-ROM %i: CDROM_PHASE_COMMAND\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_COMMAND\n", id); cdrom[id].status = BUSY_STAT | (cdrom[id].status &ERR_STAT); memcpy(cdrom[id].atapi_cdb, (uint8_t *) cdrom[id].buffer, cdrom[id].cdb_len); cdrom_command(id, cdrom[id].atapi_cdb); - return 0; + return; case CDROM_PHASE_COMPLETE: - // cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", id); cdrom[id].status = READY_STAT; cdrom[id].phase = 3; cdrom[id].packet_status = 0xFF; - return 1; + cdrom_irq_raise(id); + return; case CDROM_PHASE_DATA_OUT: - // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", id); cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); cdrom[id].phase = 0; - return 1; + cdrom_irq_raise(id); + return; case CDROM_PHASE_DATA_OUT_DMA: - // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT_DMA\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT_DMA\n", id); cdrom_read_from_dma(id); cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; - return 1; + cdrom_irq_raise(id); + return; case CDROM_PHASE_DATA_IN: - // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", id); cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); cdrom[id].phase = 2; - return 1; + cdrom_irq_raise(id); + return; case CDROM_PHASE_DATA_IN_DMA: - // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN_DMA\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN_DMA\n", id); cdrom_write_to_dma(id); cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; - return 1; + cdrom_irq_raise(id); + return; case CDROM_PHASE_ERROR: - // cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id); cdrom[id].status = READY_STAT | ERR_STAT; cdrom[id].phase = 3; - return 1; + cdrom_irq_raise(id); + return; } } @@ -2957,7 +2970,7 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) cdrom[id].pos++; break; case 2: - cdbufferw[cdrom[id].pos >> 1] = val & 0xff; + cdbufferw[cdrom[id].pos >> 1] = val & 0xffff; cdrom[id].pos += 2; break; case 4: diff --git a/src/cdrom.h b/src/cdrom.h index 759c5e134..25c9bc201 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -129,9 +129,6 @@ typedef struct __attribute__((__packed__)) uint8_t bus_mode; /* Bit 0 = PIO suported; Bit 1 = DMA supportd. */ - uint8_t check_on_execution; /* 0 = Not Ready/Unit Attention checkeck is performed on the controller's side before command execution; - 1 = Not Ready/Unit Attention checkeck is performed on command execution. */ - uint8_t ide_channel; uint8_t scsi_device_id; @@ -190,7 +187,7 @@ void build_scsi_cdrom_map(); int cdrom_CDROM_PHASE_to_scsi(uint8_t id); int cdrom_atapi_phase_to_scsi(uint8_t id); void cdrom_command(uint8_t id, uint8_t *cdb); -int cdrom_phase_callback(uint8_t id); +void cdrom_phase_callback(uint8_t id); uint32_t cdrom_read(uint8_t channel, int length); void cdrom_write(uint8_t channel, uint32_t val, int length); int cdrom_lba_to_msf_accurate(int lba); diff --git a/src/ide.c b/src/ide.c index 5c4063f01..c1dca50e6 100644 --- a/src/ide.c +++ b/src/ide.c @@ -202,7 +202,7 @@ int image_is_hdi(const char *s) int ide_enable[4] = { 1, 1, 0, 0 }; int ide_irq[4] = { 14, 15, 10, 11 }; -static inline void ide_irq_raise(IDE *ide) +void ide_irq_raise(IDE *ide) { if ((ide->board > 3) || ide->irqstat) { @@ -344,7 +344,7 @@ static void ide_identify(IDE *ide) h = hdc[cur_ide[ide->board]].hpc; /* Heads */ s = hdc[cur_ide[ide->board]].spt; /* Sectors */ - ide->buffer[0] = 0x40; /* Fixed disk */ + // ide->buffer[0] = 0x40; /* Fixed disk */ ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ ide->buffer[3] = hdc[cur_ide[ide->board]].hpc; /* Heads */ ide->buffer[6] = hdc[cur_ide[ide->board]].spt; /* Sectors */ @@ -403,10 +403,11 @@ static void ide_atapi_identify(IDE *ide) ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ + ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] = 0x200; /* LBA supported */ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ ide->buffer[73] = 6; - ide->buffer[73] = 9; + ide->buffer[74] = 9; ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/ if ((ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) @@ -736,7 +737,7 @@ void resetide(void) if (ide_drives[d].type != IDE_NONE) { ide_drives[d].dma_identify_data[0] = 7; - ide_drives[d].dma_identify_data[1] = 7 | (1 << 15); + ide_drives[d].dma_identify_data[1] = 7 | (1 << 10); ide_drives[d].dma_identify_data[2] = 0x3f; } @@ -835,7 +836,9 @@ void writeidew(int ide_board, uint16_t val) void writeidel(int ide_board, uint32_t val) { // ide_log("WriteIDEl %08X\n", val); - ide_write_data(ide_board, val, 4); + // ide_write_data(ide_board, val, 4); + writeidew(ide_board, val); + writeidew(ide_board, val >> 16); } void writeide(int ide_board, uint16_t addr, uint8_t val) @@ -1349,7 +1352,7 @@ uint32_t ide_read_data(int ide_board, int length) ide->pos += 2; break; case 4: - temp = idebufferb[ide->pos >> 2]; + temp = idebufferl[ide->pos >> 2]; ide->pos += 4; break; default: @@ -1559,17 +1562,21 @@ int all_blocks_total = 0; uint16_t readidew(int ide_board) { - uint16_t temp; - temp = ide_read_data(ide_board, 2); - return temp; + return ide_read_data(ide_board, 2); } +/* uint32_t readidel(int ide_board) +{ + // ide_log("Read IDEl %i\n", ide_board); + return ide_read_data(ide_board, 4); +} */ + uint32_t readidel(int ide_board) { uint16_t temp; - // ide_log("Read IDEl %i\n", ide_board); - temp = ide_read_data(ide_board, 4); - return temp; + // pclog("Read IDEl %i\n", ide_board); + temp = readidew(ide_board); + return temp | (readidew(ide_board) << 16); } int times30=0; @@ -2015,10 +2022,7 @@ void callbackide(int ide_board) goto abort_cmd; } - if (cdrom_phase_callback(atapi_cdrom_drives[cur_ide[ide_board]])) - { - ide_irq_raise(ide); - } + cdrom_phase_callback(atapi_cdrom_drives[cur_ide[ide_board]]); idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; ide_log("IDE callback now: %i\n", idecallback[ide_board]); return; diff --git a/src/ide.h b/src/ide.h index 0bd0fcac0..87dc9081c 100644 --- a/src/ide.h +++ b/src/ide.h @@ -62,6 +62,7 @@ extern int idecallback[4]; extern char ide_fn[IDE_NUM][512]; +void ide_irq_raise(IDE *ide); void ide_irq_lower(IDE *ide); IDE ide_drives[IDE_NUM]; diff --git a/src/scsi.c b/src/scsi.c index 17f573b14..6a3c5746e 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -16,22 +16,6 @@ uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE; uint8_t SCSIStatus = SCSI_STATUS_OK; -int SCSICallback[16][8] = { { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 } }; uint8_t scsi_cdrom_id = 3; /*common setting*/ //Initialization function for the SCSI layer @@ -41,8 +25,6 @@ void SCSIReset(uint8_t id, uint8_t lun) if (buslogic_scsi_drive_is_cdrom(id, lun)) { - SCSICallback[id][lun] = 0; - cdrom_reset(cdrom_id); SCSIDevices[id][lun].LunType = SCSI_CDROM; } diff --git a/src/scsi.h b/src/scsi.h index 125131732..b3f4becaf 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -188,7 +188,6 @@ int MediaPresent; extern uint8_t SCSIStatus; extern uint8_t SCSIPhase; -extern int SCSICallback[16][8]; extern uint8_t scsi_cdrom_id; struct