Kernel - MMap fixed (non-fixed mappings, bad search), SHM mmap only working
[tpg/acess2.git] / KernelLand / Modules / Storage / ATA / io.c
index da0447a..c3258bc 100644 (file)
@@ -124,7 +124,7 @@ int ATA_SetupIO(void)
        LOG("ent = %i", 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");
+               Log_Warning("ATA", "Unable to find a Bus Master DMA controller");
                // TODO: Use PIO mode instead
                LEAVE('i', MODULE_ERR_NOTNEEDED);
                return MODULE_ERR_NOTNEEDED;
@@ -132,19 +132,43 @@ int ATA_SetupIO(void)
        
        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) )
+       if( gATA_BusMasterBase & 1 )
        {
-               if( gATA_BusMasterBase < 0x100000 )
-                       gATA_BusMasterBasePtr = (void*)(KERNEL_BASE | (tVAddr)gATA_BusMasterBase);
-               else
-                       gATA_BusMasterBasePtr = (void*)( MM_MapHWPages( gATA_BusMasterBase, 1 ) + (gATA_BusMasterBase&0xFFF) );
-               LOG("gATA_BusMasterBasePtr = %p", gATA_BusMasterBasePtr);
+               gATA_BusMasterBase &= ~1;
+               LOG("gATA_BusMasterBase = IO 0x%x", gATA_BusMasterBase);
        }
-       else {
-               // Bit 0 is left set as a flag to other functions
-               LOG("gATA_BusMasterBase = IO 0x%x", gATA_BusMasterBase & ~1);
+       else
+       {
+               // MMIO
+               gATA_BusMasterBasePtr = MM_MapHWPages( gATA_BusMasterBase, 1 ) + (gATA_BusMasterBase&0xFFF);
+               LOG("gATA_BusMasterBasePtr = %p", gATA_BusMasterBasePtr);
        }
 
        // Register IRQs and get Buffers
@@ -159,11 +183,11 @@ int ATA_SetupIO(void)
 
        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]);
@@ -179,6 +203,14 @@ int ATA_SetupIO(void)
        outb(IDE_SEC_BASE+1, 1);
        outb(IDE_PRI_CTRL, 0);
        outb(IDE_SEC_CTRL, 0);
+
+       
+       // Soft reset all drives
+       outb(IDE_PRI_CTRL, 4);
+       outb(IDE_SEC_CTRL, 4);
+       IO_DELAY();
+       outb(IDE_PRI_CTRL, 0);
+       outb(IDE_SEC_CTRL, 0);
        
        // Make sure interrupts are ACKed
        ATA_int_BusMasterWriteByte(2, 0x4);
@@ -204,35 +236,16 @@ Uint64 ATA_GetDiskSize(int Disk)
        }       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();
@@ -244,15 +257,22 @@ Uint64 ATA_GetDiskSize(int Disk)
        }
 
        // 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);
@@ -260,7 +280,7 @@ Uint64 ATA_GetDiskSize(int Disk)
        }
 
        // Read Data
-       for( i = 0; i < 256; i++ )
+       for( int i = 0; i < 256; i++ )
                data.buf[i] = inw(base);
 
        // Return the disk size
@@ -293,7 +313,7 @@ int ATA_DoDMA(Uint8 Disk, Uint64 Address, Uint Count, int bWrite, void *Buffer)
         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);
 
@@ -351,21 +371,6 @@ int ATA_DoDMA(Uint8 Disk, Uint64 Address, Uint Count, int bWrite, void *Buffer)
        // Reset IRQ Flag
        gaATA_IRQs[cont] = 0;
 
-       
-       // TODO: What the ____ does this do?
-       #if 1
-       if( cont == 0 ) {
-               outb(IDE_PRI_CTRL, 4);
-               IO_DELAY();
-               outb(IDE_PRI_CTRL, 0);
-       }
-       else {
-               outb(IDE_SEC_CTRL, 4);
-               IO_DELAY();
-               outb(IDE_SEC_CTRL, 0);
-       }
-       #endif
-
        // Set up transfer
        if( Address > 0x0FFFFFFF )      // Use LBA48
        {
@@ -534,10 +539,10 @@ void ATA_IRQHandlerSec(int UNUSED(IRQ), void *UNUSED(Ptr))
  */
 Uint8 ATA_int_BusMasterReadByte(int Ofs)
 {
-       if( gATA_BusMasterBase & 1 )
-               return inb( (gATA_BusMasterBase & ~1) + Ofs );
-       else
+       if( gATA_BusMasterBasePtr )
                return *(Uint8*)(gATA_BusMasterBasePtr + Ofs);
+       else
+               return inb( gATA_BusMasterBase + Ofs );
 }
 
 /**
@@ -546,10 +551,10 @@ Uint8 ATA_int_BusMasterReadByte(int Ofs)
  */
 Uint32 ATA_int_BusMasterReadDWord(int Ofs)
 {
-       if( gATA_BusMasterBase & 1 )
-               return ind( (gATA_BusMasterBase & ~1) + Ofs );
-       else
+       if( gATA_BusMasterBasePtr )
                return *(Uint32*)(gATA_BusMasterBasePtr + Ofs);
+       else
+               return ind( gATA_BusMasterBase + Ofs );
 }
 
 /**
@@ -559,10 +564,10 @@ Uint32 ATA_int_BusMasterReadDWord(int Ofs)
  */
 void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
 {
-       if( gATA_BusMasterBase & 1 )
-               outb( (gATA_BusMasterBase & ~1) + Ofs, Value );
-       else
+       if( gATA_BusMasterBasePtr )
                *(Uint8*)(gATA_BusMasterBasePtr + Ofs) = Value;
+       else
+               outb( gATA_BusMasterBase + Ofs, Value );
 }
 
 /**
@@ -572,8 +577,8 @@ void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
  */
 void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
 {
-       if( gATA_BusMasterBase & 1 )
-               outd( (gATA_BusMasterBase & ~1) + Ofs, Value );
-       else
+       if( gATA_BusMasterBasePtr )
                *(Uint32*)(gATA_BusMasterBasePtr + Ofs) = Value;
+       else
+               outd( gATA_BusMasterBase + Ofs, Value );
 }

UCC git Repository :: git.ucc.asn.au