*
* Disk Input/Output control
*/
-#define DEBUG 1
+#define DEBUG 0
#include <acess.h>
#include <modules.h> // Needed for error codes
#include <drv_pci.h>
int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer);
// IRQs
-void ATA_IRQHandlerPri(int UNUSED(IRQ));
-void ATA_IRQHandlerSec(int UNUSED(IRQ));
+void ATA_IRQHandlerPri(int UNUSED(IRQ), void *UNUSED(Ptr));
+void ATA_IRQHandlerSec(int UNUSED(IRQ), void *UNUSED(Ptr));
// Controller IO
Uint8 ATA_int_BusMasterReadByte(int Ofs);
Uint32 ATA_int_BusMasterReadDWord(int Ofs);
// Get IDE Controller's PCI Entry
ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1);
LOG("ent = %i", ent);
- gATA_BusMasterBase = PCI_GetBAR4( ent );
+ gATA_BusMasterBase = PCI_GetBAR(ent, 4);
if( gATA_BusMasterBase == 0 ) {
Log_Warning("ATA", "It seems that there is no Bus Master Controller on this machine. Get one");
// TODO: Use PIO mode instead
return MODULE_ERR_NOTNEEDED;
}
- LOG("BAR5 = 0x%x", PCI_GetBAR5( ent ));
- LOG("IRQ = %i", PCI_GetIRQ( ent ));
+ LOG("BAR5 = 0x%x", PCI_GetBAR(ent, 5));
+ LOG("IRQ = %i", PCI_GetIRQ(ent));
// Map memory
if( !(gATA_BusMasterBase & 1) )
}
else {
// Bit 0 is left set as a flag to other functions
- LOG("gATA_BusMasterBase = 0x%x", gATA_BusMasterBase & ~1);
+ LOG("gATA_BusMasterBase = IO 0x%x", gATA_BusMasterBase & ~1);
}
// Register IRQs and get Buffers
- IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri );
- IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec );
+ IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri, NULL );
+ IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec, NULL );
gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[0] );
gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[1] );
// Enable controllers
outb(IDE_PRI_BASE+1, 1);
outb(IDE_SEC_BASE+1, 1);
+ outb(IDE_PRI_CTRL, 0);
+ outb(IDE_SEC_CTRL, 0);
// Make sure interrupts are ACKed
ATA_int_BusMasterWriteByte(2, 0x4);
#if 1
if( cont == 0 ) {
- outb(base+IDE_PRI_CTRL, 4);
+ outb(IDE_PRI_CTRL, 4);
IO_DELAY();
- outb(base+IDE_PRI_CTRL, 0);
+ outb(IDE_PRI_CTRL, 0);
}
else {
- outb(base+IDE_SEC_CTRL, 4);
+ outb(IDE_SEC_CTRL, 4);
IO_DELAY();
- outb(base+IDE_SEC_CTRL, 0);
+ outb(IDE_SEC_CTRL, 0);
}
#endif
// HACK: Ensure the PRDT is reset
ATA_int_BusMasterWriteDWord(cont*8+4, gaATA_PRDT_PAddrs[cont]);
-
+ ATA_int_BusMasterWriteByte(cont*8, 4); // Reset IRQ
+
LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes);
if( Address > 0x0FFFFFFF )
outb(base+0x07, HDD_DMA_R48); // Read Command (LBA48)
while( gaATA_IRQs[cont] == 0 && now() < timeoutTime)
{
HALT();
-// Threads_Yield();
}
// Complete Transfer
LOG("Status byte = 0x%02x, Controller Status = 0x%02x",
val, ATA_int_BusMasterReadByte(cont * 8 + 2));
- if( gaATA_IRQs[cont] == 0 ) {
-
+ if( gaATA_IRQs[cont] == 0 )
+ {
+ if( ATA_int_BusMasterReadByte(cont * 8 + 2) & 0x4 ) {
+ Log_Error("ATA", "BM Status reports an interrupt, but none recieved");
+ ATA_int_BusMasterWriteByte(cont*8 + 2, 4); // Clear interrupt
+ memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
+ Mutex_Release( &glaATA_ControllerLock[ cont ] );
+ LEAVE('i', 0);
+ return 0;
+ }
+
#if 1
Debug_HexDump("ATA", Buffer, 512);
#endif
timeoutTime = now() + ATA_TIMEOUT;
while( gaATA_IRQs[cont] == 0 && now() < timeoutTime)
{
-// Threads_Yield();
HALT();
}
/**
* \brief Primary ATA Channel IRQ handler
*/
-void ATA_IRQHandlerPri(int UNUSED(IRQ))
+void ATA_IRQHandlerPri(int UNUSED(IRQ), void *UNUSED(Ptr))
{
Uint8 val;
/**
* \brief Second ATA Channel IRQ handler
*/
-void ATA_IRQHandlerSec(int UNUSED(IRQ))
+void ATA_IRQHandlerSec(int UNUSED(IRQ), void *UNUSED(Ptr))
{
Uint8 val;
// IRQ bit set for Secondary Controller