Broke out the ATA IO functions (Read/WriteDMA into their own file to improve code...
authorJohn Hodge <[email protected]>
Sat, 31 Jul 2010 11:49:24 +0000 (19:49 +0800)
committerJohn Hodge <[email protected]>
Sat, 31 Jul 2010 11:49:24 +0000 (19:49 +0800)
Modules/Storage/ATA/Makefile
Modules/Storage/ATA/common.h
Modules/Storage/ATA/io.c [new file with mode: 0644]
Modules/Storage/ATA/main.c

index 05e66af..2292342 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-OBJ = main.o mbr.o
+OBJ = main.o io.o mbr.o
 NAME = ATA
 
 -include ../Makefile.tpl
index 18e62a8..33be007 100644 (file)
@@ -70,8 +70,16 @@ typedef struct
 extern tATA_Disk       gATA_Disks[];
 
 // === FUNCTIONS ===
+// --- Common ---
 extern void    ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length);
+
+// --- MBR Parsing ---
+extern void    ATA_ParseMBR(int Disk, tMBR *MBR);
+
+// --- IO Functions ---
+extern int     ATA_SetupIO(void);
+extern Uint64  ATA_GetDiskSize(int Disk);
 extern int     ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
-extern int     ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
+extern int     ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer);
 
 #endif
diff --git a/Modules/Storage/ATA/io.c b/Modules/Storage/ATA/io.c
new file mode 100644 (file)
index 0000000..4193377
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Acess2 IDE Harddisk Driver
+ * - io.c
+ *
+ * Disk Input/Output control
+ */
+#define DEBUG  1
+#include <acess.h>
+#include <modules.h>   // Needed for error codes
+#include <drv_pci.h>
+#include "common.h"
+
+// === MACROS ===
+#define IO_DELAY()     do{inb(0x80); inb(0x80); inb(0x80); inb(0x80);}while(0)
+
+// === TYPES ===
+/**
+ * \brief PRDT Entry
+ */
+typedef struct
+{
+       Uint32  PBufAddr;       // Physical Buffer Address
+       Uint16  Bytes;  // Size of transfer entry
+       Uint16  Flags;  // Flags
+} __attribute__ ((packed))     tPRDT_Ent;
+
+/**
+ * \brief Structure returned by the ATA IDENTIFY command
+ */
+typedef struct
+{
+       Uint16  Flags;          // 1
+       Uint16  Usused1[9];     // 10
+       char    SerialNum[20];  // 20
+       Uint16  Usused2[3];     // 23
+       char    FirmwareVer[8]; // 27
+       char    ModelNumber[40];        // 47
+       Uint16  SectPerInt;     // 48 - Low byte only
+       Uint16  Unused3;        // 49
+       Uint16  Capabilities[2];        // 51
+       Uint16  Unused4[2];     // 53
+       Uint16  ValidExtData;   // 54
+       Uint16  Unused5[5];      // 59
+       Uint16  SizeOfRWMultiple;       // 60
+       Uint32  Sectors28;      // 62
+       Uint16  Unused6[100-62];
+       Uint64  Sectors48;
+       Uint16  Unused7[256-104];
+} __attribute__ ((packed))     tIdentify;
+
+// === PROTOTYPES ===
+ int   ATA_SetupIO(void);
+Uint64 ATA_GetDiskSize(int Disk);
+Uint16 ATA_GetBasePort(int Disk);
+// Read/Write DMA
+ 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));
+// Controller IO
+Uint8  ATA_int_BusMasterReadByte(int Ofs);
+void   ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value);
+void   ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value);
+
+// === GLOBALS ===
+Uint32 gATA_BusMasterBase = 0;
+Uint8  *gATA_BusMasterBasePtr = 0;
+ int   gATA_IRQPri = 14;
+ int   gATA_IRQSec = 15;
+ int   giaATA_ControllerLock[2] = {0}; //!< Spinlocks for each controller
+Uint8  gATA_Buffers[2][(MAX_DMA_SECTORS+0xFFF)&~0xFFF] __attribute__ ((section(".padata")));
+volatile int   gaATA_IRQs[2] = {0};
+tPRDT_Ent      gATA_PRDTs[2] = {
+       {0, 512, IDE_PRDT_LAST},
+       {0, 512, IDE_PRDT_LAST}
+};
+
+// === CODE ===
+/**
+ * \brief Sets up the ATA controller's DMA mode
+ */
+int ATA_SetupIO(void)
+{
+        int    ent;
+       tPAddr  addr;
+
+       ENTER("");
+
+       // Get IDE Controller's PCI Entry
+       ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1);
+       LOG("ent = %i", ent);
+       gATA_BusMasterBase = PCI_GetBAR4( ent );
+       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
+               LEAVE('i', MODULE_ERR_NOTNEEDED);
+               return MODULE_ERR_NOTNEEDED;
+       }
+       
+       // Map memory
+       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);
+       }
+       else {
+               // Bit 0 is left set as a flag to other functions
+               LOG("gATA_BusMasterBase = 0x%x", gATA_BusMasterBase & ~1);
+       }
+
+       // Register IRQs and get Buffers
+       IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri );
+       IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec );
+
+       gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[0] );
+       gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[1] );
+
+       LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
+
+       addr = MM_GetPhysAddr( (tVAddr)&gATA_PRDTs[0] );
+       LOG("addr = 0x%x", addr);
+       ATA_int_BusMasterWriteDWord(4, addr);
+       addr = MM_GetPhysAddr( (tVAddr)&gATA_PRDTs[1] );
+       LOG("addr = 0x%x", addr);
+       ATA_int_BusMasterWriteDWord(12, addr);
+
+       // Enable controllers
+       outb(IDE_PRI_BASE+1, 1);
+       outb(IDE_SEC_BASE+1, 1);
+
+       // return
+       LEAVE('i', MODULE_ERR_OK);
+       return MODULE_ERR_OK;
+}
+
+Uint64 ATA_GetDiskSize(int Disk)
+{
+       union {
+               Uint16  buf[256];
+               tIdentify       identify;
+       }       data;
+       Uint16  base;
+       Uint8   val;
+        int    i;
+       ENTER("iDisk", Disk);
+
+       base = ATA_GetBasePort( Disk );
+
+       // Send Disk Selector
+       if(Disk == 1 || Disk == 3)
+               outb(base+6, 0xB0);
+       else
+               outb(base+6, 0xA0);
+       IO_DELAY();
+       
+       // Check for a floating bus
+       if( 0xFF == inb(base+7) ) {
+               LOG("Floating bus");
+               LEAVE('i', 0);
+               return 0;
+       }
+       
+       // Check for the controller
+       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 IDENTIFY
+       outb(base+7, 0xEC);
+       IO_DELAY();
+       val = inb(base+7);      // Read status
+       LOG("val = 0x%02x", val);
+       if(val == 0) {
+               LEAVE('i', 0);
+               return 0;       // Disk does not exist
+       }
+
+       // Poll until BSY clears and DRQ sets or ERR is set
+       while( ((val & 0x80) || !(val & 0x08)) && !(val & 1))
+               val = inb(base+7);
+
+       // Check for an error
+       if(val & 1) {
+               LEAVE('i', 0);
+               return 0;       // Error occured, so return false
+       }
+
+       // Read Data
+       for( i = 0; i < 256; i++ )
+               data.buf[i] = inw(base);
+
+       // Return the disk size
+       if(data.identify.Sectors48 != 0)
+               return data.identify.Sectors48;
+       else
+               return data.identify.Sectors28;
+}
+
+/**
+ * \fn Uint16 ATA_GetPortBase(int Disk)
+ * \brief Returns the base port for a given disk
+ */
+Uint16 ATA_GetBasePort(int Disk)
+{
+       switch(Disk)
+       {
+       case 0: case 1:         return IDE_PRI_BASE;
+       case 2: case 3:         return IDE_SEC_BASE;
+       }
+       return 0;
+}
+
+/**
+ * \fn int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
+ */
+int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
+{
+        int    cont = (Disk>>1)&1;     // Controller ID
+        int    disk = Disk & 1;
+       Uint16  base;
+       Uint8   val;
+
+       ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer);
+
+       // Check if the count is small enough
+       if(Count > MAX_DMA_SECTORS) {
+               Warning("Passed too many sectors for a bulk DMA read (%i > %i)",
+                       Count, MAX_DMA_SECTORS);
+               LEAVE('i');
+               return 0;
+       }
+
+       // Get exclusive access to the disk controller
+       LOCK( &giaATA_ControllerLock[ cont ] );
+
+       // Set Size
+       gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
+
+       // Get Port Base
+       base = ATA_GetBasePort(Disk);
+
+       // Reset IRQ Flag
+       gaATA_IRQs[cont] = 0;
+
+       // Set up transfer
+       if( Address > 0x0FFFFFFF )      // Use LBA48
+       {
+               outb(base+0x6, 0x40 | (disk << 4));
+               outb(base+0x2, 0 >> 8); // Upper Sector Count
+               outb(base+0x3, Address >> 24);  // Low 2 Addr
+               outb(base+0x4, Address >> 28);  // Mid 2 Addr
+               outb(base+0x5, Address >> 32);  // High 2 Addr
+       }
+       else
+       {
+               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); // Magic, Disk, High addr
+       }
+
+       outb(base+0x01, 0x01);  //?
+       outb(base+0x02, (Uint8) Count);         // Sector Count
+       outb(base+0x03, (Uint8) Address);               // Low Addr
+       outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
+       outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
+
+       LOG("Starting Transfer");
+       LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes);
+       if( Address > 0x0FFFFFFF )
+               outb(base+0x07, HDD_DMA_R48);   // Read Command (LBA48)
+       else
+               outb(base+0x07, HDD_DMA_R28);   // Read Command (LBA28)
+
+       // Start transfer
+       ATA_int_BusMasterWriteByte( cont << 3, 9 );     // Read and start
+
+       // Wait for transfer to complete
+       while( gaATA_IRQs[cont] == 0 )  Threads_Yield();
+
+       // Complete Transfer
+       ATA_int_BusMasterWriteByte( cont << 3, 8 );     // Read and stop
+
+       val = inb(base+0x7);
+       LOG("Status byte = 0x%02x", val);
+
+       LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes);
+       LOG("Transfer Completed & Acknowledged");
+
+       // Copy to destination buffer
+       memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
+
+       // Release controller lock
+       RELEASE( &giaATA_ControllerLock[ cont ] );
+
+       LEAVE('i', 1);
+       return 1;
+}
+
+/**
+ * \fn int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
+ * \brief Write up to \a MAX_DMA_SECTORS to a disk
+ * \param Disk Disk ID to write to
+ * \param Address      LBA of first sector
+ * \param Count        Number of sectors to write (must be >= \a MAX_DMA_SECTORS)
+ * \param Buffer       Source buffer for data
+ */
+int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer)
+{
+        int    cont = (Disk>>1)&1;     // Controller ID
+        int    disk = Disk & 1;
+       Uint16  base;
+
+       // Check if the count is small enough
+       if(Count > MAX_DMA_SECTORS)     return 0;
+
+       // Get exclusive access to the disk controller
+       LOCK( &giaATA_ControllerLock[ cont ] );
+
+       // Set Size
+       gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
+
+       // Get Port Base
+       base = ATA_GetBasePort(Disk);
+
+       // Set up transfer
+       outb(base+0x01, 0x00);
+       if( Address > 0x0FFFFFFF )      // Use LBA48
+       {
+               outb(base+0x6, 0x40 | (disk << 4));
+               outb(base+0x2, 0 >> 8); // Upper Sector Count
+               outb(base+0x3, Address >> 24);  // Low 2 Addr
+               outb(base+0x3, Address >> 28);  // Mid 2 Addr
+               outb(base+0x3, Address >> 32);  // High 2 Addr
+       }
+       else
+       {
+               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr
+       }
+
+       outb(base+0x02, (Uint8) Count);         // Sector Count
+       outb(base+0x03, (Uint8) Address);               // Low Addr
+       outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
+       outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
+       if( Address > 0x0FFFFFFF )
+               outb(base+0x07, HDD_DMA_W48);   // Write Command (LBA48)
+       else
+               outb(base+0x07, HDD_DMA_W28);   // Write Command (LBA28)
+
+       // Reset IRQ Flag
+       gaATA_IRQs[cont] = 0;
+
+       // Copy to output buffer
+       memcpy( gATA_Buffers[cont], Buffer, Count*SECTOR_SIZE );
+
+       // Start transfer
+       ATA_int_BusMasterWriteByte( cont << 3, 1 );     // Write and start
+
+       // Wait for transfer to complete
+       while( gaATA_IRQs[cont] == 0 )  Threads_Yield();
+
+       // Complete Transfer
+       ATA_int_BusMasterWriteByte( cont << 3, 0 );     // Write and stop
+
+       // Release controller lock
+       RELEASE( &giaATA_ControllerLock[ cont ] );
+
+       return 1;
+}
+
+/**
+ * \brief Primary ATA Channel IRQ handler
+ */
+void ATA_IRQHandlerPri(int UNUSED(IRQ))
+{
+       Uint8   val;
+
+       // IRQ bit set for Primary Controller
+       val = ATA_int_BusMasterReadByte( 0x2 );
+       LOG("IRQ val = 0x%x", val);
+       if(val & 4) {
+               LOG("IRQ hit (val = 0x%x)", val);
+               ATA_int_BusMasterWriteByte( 0x2, 4 );
+               gaATA_IRQs[0] = 1;
+               return ;
+       }
+}
+
+/**
+ * \brief Second ATA Channel IRQ handler
+ */
+void ATA_IRQHandlerSec(int UNUSED(IRQ))
+{
+       Uint8   val;
+       // IRQ bit set for Secondary Controller
+       val = ATA_int_BusMasterReadByte( 0xA );
+       LOG("IRQ val = 0x%x", val);
+       if(val & 4) {
+               LOG("IRQ hit (val = 0x%x)", val);
+               ATA_int_BusMasterWriteByte( 0xA, 4 );
+               gaATA_IRQs[1] = 1;
+               return ;
+       }
+}
+
+/**
+ * \brief Read an 8-bit value from a Bus Master register
+ * \param Ofs  Register offset
+ */
+Uint8 ATA_int_BusMasterReadByte(int Ofs)
+{
+       if( gATA_BusMasterBase & 1 )
+               return inb( (gATA_BusMasterBase & ~1) + Ofs );
+       else
+               return *(Uint8*)(gATA_BusMasterBasePtr + Ofs);
+}
+
+/**
+ * \brief Writes a byte to a Bus Master Register
+ * \param Ofs  Register Offset
+ * \param Value        Value to write
+ */
+void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
+{
+       if( gATA_BusMasterBase & 1 )
+               outb( (gATA_BusMasterBase & ~1) + Ofs, Value );
+       else
+               *(Uint8*)(gATA_BusMasterBasePtr + Ofs) = Value;
+}
+
+/**
+ * \brief Writes a 32-bit value to a Bus Master Register
+ * \param Ofs  Register offset
+ * \param Value        Value to write
+ */
+void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
+{
+       if( gATA_BusMasterBase & 1 )
+               outd( (gATA_BusMasterBase & ~1) + Ofs, Value );
+       else
+               *(Uint32*)(gATA_BusMasterBasePtr + Ofs) = Value;
+}
index 69d2121..9760b4d 100644 (file)
@@ -8,49 +8,17 @@
 #include <modules.h>
 #include <vfs.h>
 #include <fs_devfs.h>
-#include <drv_pci.h>
 #include <tpl_drv_common.h>
 #include <tpl_drv_disk.h>
 #include "common.h"
 
+// === MACROS ===
 #define IO_DELAY()     do{inb(0x80); inb(0x80); inb(0x80); inb(0x80);}while(0)
 
-// === STRUCTURES ===
-typedef struct
-{
-       Uint32  PBufAddr;
-       Uint16  Bytes;
-       Uint16  Flags;
-} __attribute__ ((packed))     tPRDT_Ent;
-typedef struct
-{
-       Uint16  Flags;          // 1
-       Uint16  Usused1[9];     // 10
-       char    SerialNum[20];  // 20
-       Uint16  Usused2[3];     // 23
-       char    FirmwareVer[8]; // 27
-       char    ModelNumber[40];        // 47
-       Uint16  SectPerInt;     // 48 - AND with 0xFF to get true value;
-       Uint16  Unused3;        // 49
-       Uint16  Capabilities[2];        // 51
-       Uint16  Unused4[2];     // 53
-       Uint16  ValidExtData;   // 54
-       Uint16  Unused5[5];      // 59
-       Uint16  SizeOfRWMultiple;       // 60
-       Uint32  Sectors28;      // 62
-       Uint16  Unused6[100-62];
-       Uint64  Sectors48;
-       Uint16  Unused7[256-104];
-} __attribute__ ((packed))     tIdentify;
-
-// === IMPORTS ===
-extern void    ATA_ParseMBR(int Disk, tMBR *MBR);
-
 // === PROTOTYPES ===
- int   ATA_Install();
- int   ATA_SetupIO();
-void   ATA_SetupPartitions();
-void   ATA_SetupVFS();
+ int   ATA_Install(char **Arguments);
+void   ATA_SetupPartitions(void);
+void   ATA_SetupVFS(void);
  int   ATA_ScanDisk(int Disk);
 void   ATA_ParseGPT(int Disk);
 void   ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length);
@@ -64,16 +32,6 @@ Uint64       ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
 // Read/Write Interface/Quantiser
 Uint   ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk);
 Uint   ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk);
-// Read/Write DMA
- int   ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
- int   ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
-// IRQs
-void   ATA_IRQHandlerPri(int unused);
-void   ATA_IRQHandlerSec(int unused);
-// Controller IO
-Uint8  ATA_int_BusMasterReadByte(int Ofs);
-void   ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value);
-void   ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, i386ATA, ATA_Install, NULL, "PCI", NULL);
@@ -91,23 +49,12 @@ tDevFS_Driver       gATA_DriverInfo = {
 tATA_Disk      gATA_Disks[MAX_ATA_DISKS];
  int   giATA_NumNodes;
 tVFS_Node      **gATA_Nodes;
-Uint32 gATA_BusMasterBase = 0;
-Uint8  *gATA_BusMasterBasePtr = 0;
- int   gATA_IRQPri = 14;
- int   gATA_IRQSec = 15;
- int   giaATA_ControllerLock[2] = {0}; //!< Spinlocks for each controller
-Uint8  gATA_Buffers[2][(MAX_DMA_SECTORS+0xFFF)&~0xFFF] __attribute__ ((section(".padata")));
-volatile int   gaATA_IRQs[2] = {0};
-tPRDT_Ent      gATA_PRDTs[2] = {
-       {0, 512, IDE_PRDT_LAST},
-       {0, 512, IDE_PRDT_LAST}
-};
 
 // === CODE ===
 /**
- * \fn int ATA_Install()
+ * \brief Initialise the ATA driver
  */
-int ATA_Install()
+int ATA_Install(char **Arguments)
 {
        int     ret;
 
@@ -125,70 +72,9 @@ int ATA_Install()
 }
 
 /**
- * \fn int ATA_SetupIO()
- * \brief Sets up the ATA controller's DMA mode
- */
-int ATA_SetupIO()
-{
-        int    ent;
-       tPAddr  addr;
-
-       ENTER("");
-
-       // Get IDE Controller's PCI Entry
-       ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1);
-       LOG("ent = %i", ent);
-       gATA_BusMasterBase = PCI_GetBAR4( ent );
-       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
-               LEAVE('i', MODULE_ERR_NOTNEEDED);
-               return MODULE_ERR_NOTNEEDED;
-       }
-       
-       // Map memory
-       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);
-       }
-       else {
-               // Bit 0 is left set as a flag to other functions
-               LOG("gATA_BusMasterBase = 0x%x", gATA_BusMasterBase & ~1);
-       }
-
-       // Register IRQs and get Buffers
-       IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri );
-       IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec );
-
-       gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[0] );
-       gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[1] );
-
-       LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
-
-       addr = MM_GetPhysAddr( (tVAddr)&gATA_PRDTs[0] );
-       LOG("addr = 0x%x", addr);
-       ATA_int_BusMasterWriteDWord(4, addr);
-       addr = MM_GetPhysAddr( (tVAddr)&gATA_PRDTs[1] );
-       LOG("addr = 0x%x", addr);
-       ATA_int_BusMasterWriteDWord(12, addr);
-
-       // Enable controllers
-       outb(IDE_PRI_BASE+1, 1);
-       outb(IDE_SEC_BASE+1, 1);
-
-       // return
-       LEAVE('i', MODULE_ERR_OK);
-       return MODULE_ERR_OK;
-}
-
-/**
- * \fn void ATA_SetupPartitions()
+ * \brief Scan all disks, looking for partitions
  */
-void ATA_SetupPartitions()
+void ATA_SetupPartitions(void)
 {
         int    i;
        for( i = 0; i < MAX_ATA_DISKS; i ++ )
@@ -201,10 +87,9 @@ void ATA_SetupPartitions()
 }
 
 /**
- * \fn void ATA_SetupVFS()
  * \brief Sets up the ATA drivers VFS information and registers with DevFS
  */
-void ATA_SetupVFS()
+void ATA_SetupVFS(void)
 {
         int    i, j, k;
 
@@ -234,77 +119,24 @@ void ATA_SetupVFS()
 }
 
 /**
- * \fn int ATA_ScanDisk(int Disk)
+ * \brief Scan a disk, getting the size and any paritions
+ * \param Disk Disk ID to scan
  */
 int ATA_ScanDisk(int Disk)
 {
-       union {
-               Uint16  buf[256];
-               tIdentify       identify;
-               tMBR    mbr;
-       }       data;
-       Uint16  base;
-       Uint8   val;
-        int    i;
        tVFS_Node       *node;
+       tMBR    mbr;
 
        ENTER("iDisk", Disk);
-
-       base = ATA_GetBasePort( Disk );
-
-       LOG("base = 0x%x", base);
-
-       // Send Disk Selector
-       if(Disk == 1 || Disk == 3)
-               outb(base+6, 0xB0);
-       else
-               outb(base+6, 0xA0);
-       IO_DELAY();
        
-       // Check for a floating bus
-       if( 0xFF == inb(base+7) ) {
-               LOG("Floating bus");
-               LEAVE('i', 0);
-               return 0;
-       }
-       
-       // Check for the controller
-       outb(base+0x02, 0x66);
-       outb(base+0x03, 0xFF);
-       if(inb(base+0x02) != 0x66 || inb(base+0x03) != 0xFF) {
-               LOG("No controller");
+       // Get the disk size
+       gATA_Disks[ Disk ].Sectors = ATA_GetDiskSize(Disk);
+       if(gATA_Disks[ Disk ].Sectors == 0)
+       {
                LEAVE('i', 0);
                return 0;
        }
 
-       // Send IDENTIFY
-       outb(base+7, 0xEC);
-       IO_DELAY();
-       val = inb(base+7);      // Read status
-       LOG("val = 0x%02x", val);
-       if(val == 0) {
-               LEAVE('i', 0);
-               return 0;       // Disk does not exist
-       }
-
-       // Poll until BSY clears and DRQ sets or ERR is set
-       while( ((val & 0x80) || !(val & 0x08)) && !(val & 1))   val = inb(base+7);
-
-       if(val & 1) {
-               LEAVE('i', 0);
-               return 0;       // Error occured, so return false
-       }
-
-       // Read Data
-       for(i=0;i<256;i++)      data.buf[i] = inw(base);
-
-       // Populate Disk Structure
-       if(data.identify.Sectors48 != 0)
-               gATA_Disks[ Disk ].Sectors = data.identify.Sectors48;
-       else
-               gATA_Disks[ Disk ].Sectors = data.identify.Sectors28;
-
-
        LOG("gATA_Disks[ %i ].Sectors = 0x%x", Disk, gATA_Disks[ Disk ].Sectors);
 
        {
@@ -347,17 +179,17 @@ int ATA_ScanDisk(int Disk)
        // --- Scan Partitions ---
        LOG("Reading MBR");
        // Read Boot Sector
-       ATA_ReadDMA( Disk, 0, 1, &data.mbr );
+       ATA_ReadDMA( Disk, 0, 1, &mbr );
 
        // Check for a GPT table
-       if(data.mbr.Parts[0].SystemID == 0xEE)
+       if(mbr.Parts[0].SystemID == 0xEE)
                ATA_ParseGPT(Disk);
        else    // No? Just parse the MBR
-               ATA_ParseMBR(Disk, &data.mbr);
+               ATA_ParseMBR(Disk, &mbr);
        
        #if DEBUG >= 2
-       ATA_ReadDMA( Disk, 1, 1, &data );
-       Debug_HexDump("ATA_ScanDisk", &data, 512);
+       ATA_ReadDMA( Disk, 1, 1, &mbr );
+       Debug_HexDump("ATA_ScanDisk", &mbr, 512);
        #endif
 
        LEAVE('i', 0);
@@ -404,20 +236,6 @@ void ATA_ParseGPT(int Disk)
        Warning("GPT Disks are currently unsupported (Disk %i)", Disk);
 }
 
-/**
- * \fn Uint16 ATA_GetPortBase(int Disk)
- * \brief Returns the base port for a given disk
- */
-Uint16 ATA_GetBasePort(int Disk)
-{
-       switch(Disk)
-       {
-       case 0: case 1:         return IDE_PRI_BASE;
-       case 2: case 3:         return IDE_SEC_BASE;
-       }
-       return 0;
-}
-
 /**
  * \fn char *ATA_ReadDir(tVFS_Node *Node, int Pos)
  */
@@ -626,224 +444,3 @@ Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
        if(ret != 1)    return 0;
        return done+Count;
 }
-
-/**
- * \fn int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
- */
-int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
-{
-        int    cont = (Disk>>1)&1;     // Controller ID
-        int    disk = Disk & 1;
-       Uint16  base;
-       Uint8   val;
-
-       ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer);
-
-       // Check if the count is small enough
-       if(Count > MAX_DMA_SECTORS) {
-               Warning("Passed too many sectors for a bulk DMA read (%i > %i)",
-                       Count, MAX_DMA_SECTORS);
-               LEAVE('i');
-               return 0;
-       }
-
-       // Get exclusive access to the disk controller
-       LOCK( &giaATA_ControllerLock[ cont ] );
-
-       // Set Size
-       gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
-
-       // Get Port Base
-       base = ATA_GetBasePort(Disk);
-
-       // Reset IRQ Flag
-       gaATA_IRQs[cont] = 0;
-
-       // Set up transfer
-       if( Address > 0x0FFFFFFF )      // Use LBA48
-       {
-               outb(base+0x6, 0x40 | (disk << 4));
-               outb(base+0x2, 0 >> 8); // Upper Sector Count
-               outb(base+0x3, Address >> 24);  // Low 2 Addr
-               outb(base+0x4, Address >> 28);  // Mid 2 Addr
-               outb(base+0x5, Address >> 32);  // High 2 Addr
-       }
-       else
-       {
-               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); // Magic, Disk, High addr
-       }
-
-       outb(base+0x01, 0x01);  //?
-       outb(base+0x02, (Uint8) Count);         // Sector Count
-       outb(base+0x03, (Uint8) Address);               // Low Addr
-       outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
-       outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
-
-       LOG("Starting Transfer");
-       LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes);
-       if( Address > 0x0FFFFFFF )
-               outb(base+0x07, HDD_DMA_R48);   // Read Command (LBA48)
-       else
-               outb(base+0x07, HDD_DMA_R28);   // Read Command (LBA28)
-
-       // Start transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 9 );     // Read and start
-
-       // Wait for transfer to complete
-       while( gaATA_IRQs[cont] == 0 )  Threads_Yield();
-
-       // Complete Transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 8 );     // Read and stop
-
-       val = inb(base+0x7);
-       LOG("Status byte = 0x%02x", val);
-
-       LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes);
-       LOG("Transfer Completed & Acknowledged");
-
-       // Copy to destination buffer
-       memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
-
-       // Release controller lock
-       RELEASE( &giaATA_ControllerLock[ cont ] );
-
-       LEAVE('i', 1);
-       return 1;
-}
-
-/**
- * \fn int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
- */
-int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
-{
-        int    cont = (Disk>>1)&1;     // Controller ID
-        int    disk = Disk & 1;
-       Uint16  base;
-
-       // Check if the count is small enough
-       if(Count > MAX_DMA_SECTORS)     return 0;
-
-       // Get exclusive access to the disk controller
-       LOCK( &giaATA_ControllerLock[ cont ] );
-
-       // Set Size
-       gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
-
-       // Get Port Base
-       base = ATA_GetBasePort(Disk);
-
-       // Set up transfer
-       outb(base+0x01, 0x00);
-       if( Address > 0x0FFFFFFF )      // Use LBA48
-       {
-               outb(base+0x6, 0x40 | (disk << 4));
-               outb(base+0x2, 0 >> 8); // Upper Sector Count
-               outb(base+0x3, Address >> 24);  // Low 2 Addr
-               outb(base+0x3, Address >> 28);  // Mid 2 Addr
-               outb(base+0x3, Address >> 32);  // High 2 Addr
-       }
-       else
-       {
-               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr
-       }
-
-       outb(base+0x02, (Uint8) Count);         // Sector Count
-       outb(base+0x03, (Uint8) Address);               // Low Addr
-       outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
-       outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
-       if( Address > 0x0FFFFFFF )
-               outb(base+0x07, HDD_DMA_W48);   // Write Command (LBA48)
-       else
-               outb(base+0x07, HDD_DMA_W28);   // Write Command (LBA28)
-
-       // Reset IRQ Flag
-       gaATA_IRQs[cont] = 0;
-
-       // Copy to output buffer
-       memcpy( gATA_Buffers[cont], Buffer, Count*SECTOR_SIZE );
-
-       // Start transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 1 );     // Write and start
-
-       // Wait for transfer to complete
-       while( gaATA_IRQs[cont] == 0 )  Threads_Yield();
-
-       // Complete Transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 0 );     // Write and stop
-
-       // Release controller lock
-       RELEASE( &giaATA_ControllerLock[ cont ] );
-
-       return 1;
-}
-
-/**
- * \fn void ATA_IRQHandlerPri(int unused)
- */
-void ATA_IRQHandlerPri(int UNUSED(IRQ))
-{
-       Uint8   val;
-
-       // IRQ bit set for Primary Controller
-       val = ATA_int_BusMasterReadByte( 0x2 );
-       LOG("IRQ val = 0x%x", val);
-       if(val & 4) {
-               LOG("IRQ hit (val = 0x%x)", val);
-               ATA_int_BusMasterWriteByte( 0x2, 4 );
-               gaATA_IRQs[0] = 1;
-               return ;
-       }
-}
-
-/**
- * \fn void ATA_IRQHandlerSec(int unused)
- */
-void ATA_IRQHandlerSec(int UNUSED(IRQ))
-{
-       Uint8   val;
-       // IRQ bit set for Secondary Controller
-       val = ATA_int_BusMasterReadByte( 0xA );
-       LOG("IRQ val = 0x%x", val);
-       if(val & 4) {
-               LOG("IRQ hit (val = 0x%x)", val);
-               ATA_int_BusMasterWriteByte( 0xA, 4 );
-               gaATA_IRQs[1] = 1;
-               return ;
-       }
-}
-
-/**
- * \fn Uint8 ATA_int_BusMasterReadByte(int Ofs)
- */
-Uint8 ATA_int_BusMasterReadByte(int Ofs)
-{
-       if( gATA_BusMasterBase & 1 )
-               return inb( (gATA_BusMasterBase & ~1) + Ofs );
-       else
-               return *(Uint8*)(gATA_BusMasterBasePtr + Ofs);
-}
-
-/**
- * \fn void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
- * \brief Writes a byte to a Bus Master Register
- */
-void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
-{
-       if( gATA_BusMasterBase & 1 )
-               outb( (gATA_BusMasterBase & ~1) + Ofs, Value );
-       else
-               *(Uint8*)(gATA_BusMasterBasePtr + Ofs) = Value;
-}
-
-/**
- * \fn void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
- * \brief Writes a dword to a Bus Master Register
- */
-void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
-{
-
-       if( gATA_BusMasterBase & 1 )
-               outd( (gATA_BusMasterBase & ~1) + Ofs, Value );
-       else
-               *(Uint32*)(gATA_BusMasterBasePtr + Ofs) = Value;
-}

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