LOG("BAR5 = 0x%x", PCI_GetBAR(ent, 5));
LOG("IRQ = %i", PCI_GetIRQ(ent));
+
+ // Ensure controllers are present where we think they should be
+ for( int i = 0; i < 2; i ++ )
+ {
+ Uint16 base = ATA_GetBasePort( i*2 );
+ // Send Disk Selector
+ outb(base+6, 0xA0);
+ IO_DELAY();
+ // Check for a floating bus
+ if( 0xFF == inb(base+7) ) {
+ Log_Error("ATA", "Floating bus at address 0x%x", base+7);
+ LEAVE('i', MODULE_ERR_MISC);
+ return MODULE_ERR_MISC;
+ }
+
+ // Check for the controller
+ // - Write to two RW ports and attempt to read back
+ outb(base+0x02, 0x66);
+ outb(base+0x03, 0xFF);
+ if(inb(base+0x02) != 0x66 || inb(base+0x03) != 0xFF) {
+ Log_Error("ATA", "Unable to write to 0x%x/0x%x", base+2, base+3);
+ LEAVE('i', MODULE_ERR_MISC);
+ return MODULE_ERR_MISC;
+ }
+ }
// Map memory
if( gATA_BusMasterBase & 1 )
LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
- // TODO: Ensure that this is within 32-bits
gaATA_PRDT_PAddrs[0] = MM_GetPhysAddr( &gATA_PRDTs[0] );
gaATA_PRDT_PAddrs[1] = MM_GetPhysAddr( &gATA_PRDTs[1] );
LOG("gaATA_PRDT_PAddrs = {0x%P, 0x%P}", gaATA_PRDT_PAddrs[0], gaATA_PRDT_PAddrs[1]);
#if PHYS_BITS > 32
+ // Ensure that this is within 32-bits
if( gaATA_PRDT_PAddrs[0] >> 32 || gaATA_PRDT_PAddrs[1] >> 32 ) {
Log_Error("ATA", "Physical addresses of PRDTs are not in 32-bits (%P and %P)",
gaATA_PRDT_PAddrs[0], gaATA_PRDT_PAddrs[1]);
} data;
Uint16 base;
Uint8 val;
- int i;
+
ENTER("iDisk", Disk);
base = ATA_GetBasePort( Disk );
// Send Disk Selector
- if(Disk & 1) // Slave
- outb(base+6, 0xB0);
- else // Master
- outb(base+6, 0xA0);
+ // - Slave / Master
+ outb(base+6, 0xA0 | (Disk & 1) << 4);
IO_DELAY();
- // Check for a floating bus
- if( 0xFF == inb(base+7) ) {
- LOG("Floating bus");
- LEAVE('i', 0);
- return 0;
- }
-
- // Check for the controller
- // - Write to two RW ports and attempt to read back
- outb(base+0x02, 0x66);
- outb(base+0x03, 0xFF);
- if(inb(base+0x02) != 0x66 || inb(base+0x03) != 0xFF) {
- LOG("No controller");
- LEAVE('i', 0);
- return 0;
- }
-
// Send ATA IDENTIFY
outb(base+7, HDD_IDENTIFY);
IO_DELAY();
}
// Poll until BSY clears or ERR is set
+ tTime endtime = now() + 2*1000; // 2 second timeout
// TODO: Timeout?
- while( (val & 0x80) && !(val & 1) )
+ while( (val & 0x80) && !(val & 1) && now() < endtime )
val = inb(base+7);
LOG("BSY unset (0x%x)", val);
// and, wait for DRQ to set
- while( !(val & 0x08) && !(val & 1))
+ while( !(val & 0x08) && !(val & 1) && now() < endtime )
val = inb(base+7);
LOG("DRQ set (0x%x)", val);
+ if(now() >= endtime) {
+ Log_Warning("ATA", "Timeout on ATA IDENTIFY (Disk %i)", Disk);
+ LEAVE('i', 0);
+ return 0;
+ }
+
// Check for an error
if(val & 1) {
LEAVE('i', 0);
}
// Read Data
- for( i = 0; i < 256; i++ )
+ for( int i = 0; i < 256; i++ )
data.buf[i] = inw(base);
// Return the disk size
int cont = (Disk>>1)&1; // Controller ID
int disk = Disk & 1;
Uint16 base;
- int bUseBounceBuffer;
+ int bUseBounceBuffer = 0;
ENTER("iDisk XAddress iCount bbWrite pBuffer", Disk, Address, Count, bWrite, Buffer);