[FREELDR]
[reactos.git] / reactos / boot / freeldr / freeldr / arch / i386 / pcdisk.c
index 6a04730..a78c369 100644 (file)
@@ -25,16 +25,16 @@ DBG_DEFAULT_CHANNEL(DISK);
 #include <pshpack2.h>
 typedef struct
 {
-       UCHAR           PacketSize;                             // 00h - Size of packet (10h or 18h)
-       UCHAR           Reserved;                               // 01h - Reserved (0)
-       USHORT          LBABlockCount;                  // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
-       USHORT          TransferBufferOffset;   // 04h - Transfer buffer offset (seg:off)
-       USHORT          TransferBufferSegment;  //       Transfer buffer segment (seg:off)
-       ULONGLONG               LBAStartBlock;                  // 08h - Starting absolute block number
-       //ULONGLONG             TransferBuffer64;               // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
-                                                                       //       used if DWORD at 04h is FFFFh:FFFFh
-                                                                       //       Commented since some earlier BIOSes refuse to work with
-                                                                       //       such extended structure
+    UCHAR        PacketSize;                // 00h - Size of packet (10h or 18h)
+    UCHAR        Reserved;                // 01h - Reserved (0)
+    USHORT        LBABlockCount;            // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
+    USHORT        TransferBufferOffset;    // 04h - Transfer buffer offset (seg:off)
+    USHORT        TransferBufferSegment;    //       Transfer buffer segment (seg:off)
+    ULONGLONG        LBAStartBlock;            // 08h - Starting absolute block number
+    //ULONGLONG        TransferBuffer64;        // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
+                                    //       used if DWORD at 04h is FFFFh:FFFFh
+                                    //       Commented since some earlier BIOSes refuse to work with
+                                    //       such extended structure
 } I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
 #include <poppack.h>
 
@@ -44,259 +44,259 @@ typedef struct
 
 static BOOLEAN PcDiskResetController(UCHAR DriveNumber)
 {
-       REGS    RegsIn;
-       REGS    RegsOut;
+    REGS    RegsIn;
+    REGS    RegsOut;
 
-       WARN("PcDiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
+    WARN("PcDiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
 
-       // BIOS Int 13h, function 0 - Reset disk system
-       // AH = 00h
-       // DL = drive (if bit 7 is set both hard disks and floppy disks reset)
-       // Return:
-       // AH = status
-       // CF clear if successful
-       // CF set on error
-       RegsIn.b.ah = 0x00;
-       RegsIn.b.dl = DriveNumber;
+    // BIOS Int 13h, function 0 - Reset disk system
+    // AH = 00h
+    // DL = drive (if bit 7 is set both hard disks and floppy disks reset)
+    // Return:
+    // AH = status
+    // CF clear if successful
+    // CF set on error
+    RegsIn.b.ah = 0x00;
+    RegsIn.b.dl = DriveNumber;
 
-       // Reset the disk controller
-       Int386(0x13, &RegsIn, &RegsOut);
+    // Reset the disk controller
+    Int386(0x13, &RegsIn, &RegsOut);
 
-       return INT386_SUCCESS(RegsOut);
+    return INT386_SUCCESS(RegsOut);
 }
 
 static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 {
-       REGS                                            RegsIn;
-       REGS                                            RegsOut;
-       ULONG                                                   RetryCount;
-       PI386_DISK_ADDRESS_PACKET       Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
+    REGS                        RegsIn;
+    REGS                        RegsOut;
+    ULONG                            RetryCount;
+    PI386_DISK_ADDRESS_PACKET    Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
 
-       TRACE("PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
+    TRACE("PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
     ASSERT(((ULONG_PTR)Buffer) <= 0xFFFFF);
 
-       // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
-       RegsIn.b.ah = 0x42;                                     // Subfunction 42h
-       RegsIn.b.dl = DriveNumber;                      // Drive number in DL (0 - floppy, 0x80 - harddisk)
-       RegsIn.x.ds = BIOSCALLBUFSEGMENT;       // DS:SI -> disk address packet
-       RegsIn.w.si = BIOSCALLBUFOFFSET;
-
-       // Setup disk address packet
-       RtlZeroMemory(Packet, sizeof(I386_DISK_ADDRESS_PACKET));
-       Packet->PacketSize = sizeof(I386_DISK_ADDRESS_PACKET);
-       Packet->Reserved = 0;
-       Packet->LBABlockCount = (USHORT)SectorCount;
-       ASSERT(Packet->LBABlockCount == SectorCount);
-       Packet->TransferBufferOffset = ((ULONG_PTR)Buffer) & 0x0F;
-       Packet->TransferBufferSegment = (USHORT)(((ULONG_PTR)Buffer) >> 4);
-       Packet->LBAStartBlock = SectorNumber;
-
-       // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
-       // Return:
-       // CF clear if successful
-       // AH = 00h
-       // CF set on error
-       // AH = error code
-       // disk address packet's block count field set to the
-       // number of blocks successfully transferred
-
-       // Retry 3 times
-       for (RetryCount=0; RetryCount<3; RetryCount++)
-       {
-               Int386(0x13, &RegsIn, &RegsOut);
-
-               // If it worked return TRUE
-               if (INT386_SUCCESS(RegsOut))
-               {
-                       return TRUE;
-               }
-               // If it was a corrected ECC error then the data is still good
-               else if (RegsOut.b.ah == 0x11)
-               {
-                       return TRUE;
-               }
-               // If it failed the do the next retry
-               else
-               {
-                       PcDiskResetController(DriveNumber);
-
-                       continue;
-               }
-       }
-
-       // If we get here then the read failed
-       ERR("Disk Read Failed in LBA mode: %x (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n", RegsOut.b.ah, DriveNumber, SectorNumber, SectorCount);
-
-       return FALSE;
+    // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
+    RegsIn.b.ah = 0x42;                    // Subfunction 42h
+    RegsIn.b.dl = DriveNumber;            // Drive number in DL (0 - floppy, 0x80 - harddisk)
+    RegsIn.x.ds = BIOSCALLBUFSEGMENT;    // DS:SI -> disk address packet
+    RegsIn.w.si = BIOSCALLBUFOFFSET;
+
+    // Setup disk address packet
+    RtlZeroMemory(Packet, sizeof(I386_DISK_ADDRESS_PACKET));
+    Packet->PacketSize = sizeof(I386_DISK_ADDRESS_PACKET);
+    Packet->Reserved = 0;
+    Packet->LBABlockCount = (USHORT)SectorCount;
+    ASSERT(Packet->LBABlockCount == SectorCount);
+    Packet->TransferBufferOffset = ((ULONG_PTR)Buffer) & 0x0F;
+    Packet->TransferBufferSegment = (USHORT)(((ULONG_PTR)Buffer) >> 4);
+    Packet->LBAStartBlock = SectorNumber;
+
+    // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
+    // Return:
+    // CF clear if successful
+    // AH = 00h
+    // CF set on error
+    // AH = error code
+    // disk address packet's block count field set to the
+    // number of blocks successfully transferred
+
+    // Retry 3 times
+    for (RetryCount=0; RetryCount<3; RetryCount++)
+    {
+        Int386(0x13, &RegsIn, &RegsOut);
+
+        // If it worked return TRUE
+        if (INT386_SUCCESS(RegsOut))
+        {
+            return TRUE;
+        }
+        // If it was a corrected ECC error then the data is still good
+        else if (RegsOut.b.ah == 0x11)
+        {
+            return TRUE;
+        }
+        // If it failed the do the next retry
+        else
+        {
+            PcDiskResetController(DriveNumber);
+
+            continue;
+        }
+    }
+
+    // If we get here then the read failed
+    ERR("Disk Read Failed in LBA mode: %x (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n", RegsOut.b.ah, DriveNumber, SectorNumber, SectorCount);
+
+    return FALSE;
 }
 
 static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 {
-       UCHAR                   PhysicalSector;
-       UCHAR                   PhysicalHead;
-       ULONG                   PhysicalTrack;
-       GEOMETRY        DriveGeometry;
-       ULONG                   NumberOfSectorsToRead;
-       REGS            RegsIn;
-       REGS            RegsOut;
-       ULONG                   RetryCount;
-
-       TRACE("PcDiskReadLogicalSectorsCHS()\n");
-
-       //
-       // Get the drive geometry
-       //
-       if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry) ||
-           DriveGeometry.Sectors == 0 ||
-           DriveGeometry.Heads == 0)
-       {
-               return FALSE;
-       }
-
-       while (SectorCount)
-       {
-
-               //
-               // Calculate the physical disk offsets
-               // Note: DriveGeometry.Sectors < 64
-               //
-               PhysicalSector = 1 + (UCHAR)(SectorNumber % DriveGeometry.Sectors);
-               PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads);
-               PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads);
-
-               //
-               // Calculate how many sectors we need to read this round
-               //
-               if (PhysicalSector > 1)
-               {
-                       if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
-                               NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
-                       else
-                               NumberOfSectorsToRead = SectorCount;
-               }
-               else
-               {
-                       if (SectorCount >= DriveGeometry.Sectors)
-                               NumberOfSectorsToRead = DriveGeometry.Sectors;
-                       else
-                               NumberOfSectorsToRead = SectorCount;
-               }
-
-               //
-               // Make sure the read is within the geometry boundaries
-               //
-               if ((PhysicalHead >= DriveGeometry.Heads) ||
-                       (PhysicalTrack >= DriveGeometry.Cylinders) ||
-                       ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
-                       (PhysicalSector > DriveGeometry.Sectors))
-               {
-                       DiskError("Disk read exceeds drive geometry limits.", 0);
-                       return FALSE;
-               }
-
-               // BIOS Int 13h, function 2 - Read Disk Sectors
-               // AH = 02h
-               // AL = number of sectors to read (must be nonzero)
-               // CH = low eight bits of cylinder number
-               // CL = sector number 1-63 (bits 0-5)
-               //      high two bits of cylinder (bits 6-7, hard disk only)
-               // DH = head number
-               // DL = drive number (bit 7 set for hard disk)
-               // ES:BX -> data buffer
-               // Return:
-               // CF set on error
-               // if AH = 11h (corrected ECC error), AL = burst length
-               // CF clear if successful
-               // AH = status
-               // AL = number of sectors transferred
-               //  (only valid if CF set for some BIOSes)
-               RegsIn.b.ah = 0x02;
-               RegsIn.b.al = (UCHAR)NumberOfSectorsToRead;
-               RegsIn.b.ch = (PhysicalTrack & 0xFF);
-               RegsIn.b.cl = (UCHAR)(PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
-               RegsIn.b.dh = PhysicalHead;
-               RegsIn.b.dl = DriveNumber;
-               RegsIn.w.es = (USHORT)(((ULONG_PTR)Buffer) >> 4);
-               RegsIn.w.bx = ((ULONG_PTR)Buffer) & 0x0F;
-
-               //
-               // Perform the read
-               // Retry 3 times
-               //
-               for (RetryCount=0; RetryCount<3; RetryCount++)
-               {
-                       Int386(0x13, &RegsIn, &RegsOut);
-
-                       // If it worked break out
-                       if (INT386_SUCCESS(RegsOut))
-                       {
-                               break;
-                       }
-                       // If it was a corrected ECC error then the data is still good
-                       else if (RegsOut.b.ah == 0x11)
-                       {
-                               break;
-                       }
-                       // If it failed the do the next retry
-                       else
-                       {
-                               PcDiskResetController(DriveNumber);
-
-                               continue;
-                       }
-               }
-
-               // If we retried 3 times then fail
-               if (RetryCount >= 3)
-               {
-                       ERR("Disk Read Failed in CHS mode, after retrying 3 times: %x\n", RegsOut.b.ah);
-                       return FALSE;
-               }
-
-               // I have learned that not all bioses return
-               // the sector read count in the AL register (at least mine doesn't)
-               // even if the sectors were read correctly. So instead
-               // of checking the sector read count we will rely solely
-               // on the carry flag being set on error
-
-               Buffer = (PVOID)((ULONG_PTR)Buffer + (NumberOfSectorsToRead * DriveGeometry.BytesPerSector));
-               SectorCount -= NumberOfSectorsToRead;
-               SectorNumber += NumberOfSectorsToRead;
-       }
-
-       return TRUE;
+    UCHAR            PhysicalSector;
+    UCHAR            PhysicalHead;
+    ULONG            PhysicalTrack;
+    GEOMETRY    DriveGeometry;
+    ULONG            NumberOfSectorsToRead;
+    REGS        RegsIn;
+    REGS        RegsOut;
+    ULONG            RetryCount;
+
+    TRACE("PcDiskReadLogicalSectorsCHS()\n");
+
+    //
+    // Get the drive geometry
+    //
+    if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry) ||
+        DriveGeometry.Sectors == 0 ||
+        DriveGeometry.Heads == 0)
+    {
+        return FALSE;
+    }
+
+    while (SectorCount)
+    {
+
+        //
+        // Calculate the physical disk offsets
+        // Note: DriveGeometry.Sectors < 64
+        //
+        PhysicalSector = 1 + (UCHAR)(SectorNumber % DriveGeometry.Sectors);
+        PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads);
+        PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads);
+
+        //
+        // Calculate how many sectors we need to read this round
+        //
+        if (PhysicalSector > 1)
+        {
+            if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
+                NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
+            else
+                NumberOfSectorsToRead = SectorCount;
+        }
+        else
+        {
+            if (SectorCount >= DriveGeometry.Sectors)
+                NumberOfSectorsToRead = DriveGeometry.Sectors;
+            else
+                NumberOfSectorsToRead = SectorCount;
+        }
+
+        //
+        // Make sure the read is within the geometry boundaries
+        //
+        if ((PhysicalHead >= DriveGeometry.Heads) ||
+            (PhysicalTrack >= DriveGeometry.Cylinders) ||
+            ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
+            (PhysicalSector > DriveGeometry.Sectors))
+        {
+            DiskError("Disk read exceeds drive geometry limits.", 0);
+            return FALSE;
+        }
+
+        // BIOS Int 13h, function 2 - Read Disk Sectors
+        // AH = 02h
+        // AL = number of sectors to read (must be nonzero)
+        // CH = low eight bits of cylinder number
+        // CL = sector number 1-63 (bits 0-5)
+        //      high two bits of cylinder (bits 6-7, hard disk only)
+        // DH = head number
+        // DL = drive number (bit 7 set for hard disk)
+        // ES:BX -> data buffer
+        // Return:
+        // CF set on error
+        // if AH = 11h (corrected ECC error), AL = burst length
+        // CF clear if successful
+        // AH = status
+        // AL = number of sectors transferred
+        //  (only valid if CF set for some BIOSes)
+        RegsIn.b.ah = 0x02;
+        RegsIn.b.al = (UCHAR)NumberOfSectorsToRead;
+        RegsIn.b.ch = (PhysicalTrack & 0xFF);
+        RegsIn.b.cl = (UCHAR)(PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
+        RegsIn.b.dh = PhysicalHead;
+        RegsIn.b.dl = DriveNumber;
+        RegsIn.w.es = (USHORT)(((ULONG_PTR)Buffer) >> 4);
+        RegsIn.w.bx = ((ULONG_PTR)Buffer) & 0x0F;
+
+        //
+        // Perform the read
+        // Retry 3 times
+        //
+        for (RetryCount=0; RetryCount<3; RetryCount++)
+        {
+            Int386(0x13, &RegsIn, &RegsOut);
+
+            // If it worked break out
+            if (INT386_SUCCESS(RegsOut))
+            {
+                break;
+            }
+            // If it was a corrected ECC error then the data is still good
+            else if (RegsOut.b.ah == 0x11)
+            {
+                break;
+            }
+            // If it failed the do the next retry
+            else
+            {
+                PcDiskResetController(DriveNumber);
+
+                continue;
+            }
+        }
+
+        // If we retried 3 times then fail
+        if (RetryCount >= 3)
+        {
+            ERR("Disk Read Failed in CHS mode, after retrying 3 times: %x\n", RegsOut.b.ah);
+            return FALSE;
+        }
+
+        // I have learned that not all bioses return
+        // the sector read count in the AL register (at least mine doesn't)
+        // even if the sectors were read correctly. So instead
+        // of checking the sector read count we will rely solely
+        // on the carry flag being set on error
+
+        Buffer = (PVOID)((ULONG_PTR)Buffer + (NumberOfSectorsToRead * DriveGeometry.BytesPerSector));
+        SectorCount -= NumberOfSectorsToRead;
+        SectorNumber += NumberOfSectorsToRead;
+    }
+
+    return TRUE;
 }
 
 BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 {
-       BOOLEAN ExtensionsSupported;
-
-       TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
-
-       //
-       // Check to see if it is a fixed disk drive
-       // If so then check to see if Int13 extensions work
-       // If they do then use them, otherwise default back to BIOS calls
-       //
-       ExtensionsSupported = DiskInt13ExtensionsSupported(DriveNumber);
-
-       if ((DriveNumber >= 0x80) && ExtensionsSupported)
-       {
-               TRACE("Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, ExtensionsSupported ? "TRUE" : "FALSE");
-
-               //
-               // LBA is easy, nothing to calculate
-               // Just do the read
-               //
-               return PcDiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer);
-       }
-       else
-       {
-               // LBA is not supported default to the CHS calls
-               return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
-       }
-
-       return TRUE;
+    BOOLEAN ExtensionsSupported;
+
+    TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
+
+    //
+    // Check to see if it is a fixed disk drive
+    // If so then check to see if Int13 extensions work
+    // If they do then use them, otherwise default back to BIOS calls
+    //
+    ExtensionsSupported = DiskInt13ExtensionsSupported(DriveNumber);
+
+    if ((DriveNumber >= 0x80) && ExtensionsSupported)
+    {
+        TRACE("Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, ExtensionsSupported ? "TRUE" : "FALSE");
+
+        //
+        // LBA is easy, nothing to calculate
+        // Just do the read
+        //
+        return PcDiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer);
+    }
+    else
+    {
+        // LBA is not supported default to the CHS calls
+        return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
+    }
+
+    return TRUE;
 }
 
 BOOLEAN
@@ -366,7 +366,7 @@ PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
 ULONG
 PcDiskGetCacheableBlockCount(UCHAR DriveNumber)
 {
-  GEOMETRY     Geometry;
+  GEOMETRY    Geometry;
 
   /* If LBA is supported then the block size will be 64 sectors (32k)
    * If not then the block size is the size of one track */