int i, j = 0, k = 4;
tMBR mbr;
Uint64 extendedLBA;
+ Uint64 base, len;
ENTER("iDisk", Disk);
}
while(extendedLBA != 0)
{
- if( ATA_ReadDMA( Disk, extendedLBA, 1, &mbr ) != 0 )
- break; // Stop on Errors
-
- extendedLBA = 0;
-
- if( mbr.Parts[0].SystemID == 0 ) continue;
- if( mbr.Parts[0].Boot == 0x0 || mbr.Parts[0].Boot == 0x80 // LBA 28
- || mbr.Parts[0].Boot == 0x1 || mbr.Parts[0].Boot == 0x81 // LBA 48
- )
- {
- if(mbr.Parts[0].SystemID == 0xF || mbr.Parts[0].SystemID == 0x7)
- extendedLBA = mbr.Parts[0].LBAStart;
- else
- gATA_Disks[Disk].NumPartitions ++;
- }
-
- if( mbr.Parts[1].SystemID == 0 ) continue;
- if( mbr.Parts[1].Boot == 0x0 || mbr.Parts[1].Boot == 0x80 // LBA 28
- || mbr.Parts[1].Boot == 0x1 || mbr.Parts[1].Boot == 0x81 // LBA 48
- )
- {
- if(mbr.Parts[1].SystemID == 0xF || mbr.Parts[1].SystemID == 0x7) {
- if(extendedLBA == 0) {
- Warning("Disk %i has twp forward link in the extended partition",
- Disk);
- break;
- }
- extendedLBA = mbr.Parts[1].LBAStart;
- }
- else {
- if(extendedLBA != 0) {
- Warning("Disk %i lacks a forward link in the extended partition",
- Disk);
- break;
- }
- gATA_Disks[Disk].NumPartitions ++;
- }
- }
+ extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
+ if( extendedLBA == -1 ) return ;
+ gATA_Disks[Disk].NumPartitions ++;
}
LOG("gATA_Disks[Disk].NumPartitions = %i", gATA_Disks[Disk].NumPartitions);
// --- Fill Partition Info ---
extendedLBA = 0;
- for( i = 0; i < 4; i ++ )
+ for( j = 0, i = 0; i < 4; i ++ )
{
Log("mbr.Parts[%i].SystemID = 0x%02x", i, mbr.Parts[i].SystemID);
if( mbr.Parts[i].SystemID == 0 ) continue;
- if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) // LBA 28
+ if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) // LBA 28
{
- if( mbr.Parts[1].SystemID == 0xF || mbr.Parts[1].SystemID == 5 ) {
- if(extendedLBA != 0) {
- Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
- continue;
- }
- extendedLBA = mbr.Parts[1].LBAStart;
- continue;
- }
- // Create Partition
- ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, i,
- mbr.Parts[i].LBAStart, mbr.Parts[i].LBALength
- );
- j ++;
- continue;
+ base = mbr.Parts[i].LBAStart;
+ len = mbr.Parts[i].LBALength;
}
- if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 ) // LBA 48
+ else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 ) // LBA 58
{
- if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
- if(extendedLBA != 0) {
- Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
- continue;
- }
- extendedLBA = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
+ base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
+ len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
+ }
+ else
+ continue;
+
+ if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
+ if(extendedLBA != 0) {
+ Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
continue;
}
- ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, i,
- (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart,
- (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength
- );
- j ++;
+ extendedLBA = base;
+ continue;
}
- // Invalid Partition, so don't count it
+ // Create Partition
+ ATA_int_MakePartition(
+ &gATA_Disks[Disk].Partitions[j], Disk, j,
+ base, len
+ );
+ j ++;
+
}
- // Scan extended partition
+ // Scan extended partitions
while(extendedLBA != 0)
{
- if( ATA_ReadDMA( Disk, extendedLBA, 1, &mbr ) != 0 )
- break; // Stop on Errors
-
- extendedLBA = 0;
+ extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
+ ATA_int_MakePartition(
+ &gATA_Disks[Disk].Partitions[j], Disk, k, base, len
+ );
+ }
+
+ LEAVE('-');
+}
+
+/**
+ * \brief Reads an extended partition
+ * \return LBA of next Extended, -1 on error, 0 for last
+ */
+Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length)
+{
+ Uint64 link = 0;
+ int bFoundPart = 0;;
+ int i;
+ tMBR mbr;
+ Uint64 base, len;
+
+ if( ATA_ReadDMA( Disk, Addr, 1, &mbr ) != 0 )
+ return -1; // Stop on Errors
+
+
+ for( i = 0; i < 4; i ++ )
+ {
+ if( mbr.Parts[i].SystemID == 0 ) continue;
- // Check first entry (should be partition)
- if( mbr.Parts[0].SystemID != 0)
- {
- if( mbr.Parts[0].Boot == 0x0 || mbr.Parts[0].Boot == 0x80 ) // LBA 28
- {
- // Forward Link to next Extended partition entry
- if(mbr.Parts[0].SystemID == 0xF || mbr.Parts[0].SystemID == 0x7)
- extendedLBA = mbr.Parts[0].LBAStart;
- else {
- ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, k,
- mbr.Parts[0].LBAStart, mbr.Parts[0].LBALength
- );
- j ++; k ++;
- }
- }
- else if( mbr.Parts[0].Boot == 0x1 || mbr.Parts[0].Boot == 0x81 ) // LBA 48
- {
- if(mbr.Parts[0].SystemID == 0xF || mbr.Parts[0].SystemID == 0x7)
- extendedLBA = (mbr.Parts[0].StartHi << 16) | mbr.Parts[0].LBAStart;
- else {
- ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, k,
- (mbr.Parts[0].StartHi << 16) | mbr.Parts[0].LBAStart,
- (mbr.Parts[0].LengthHi << 16) | mbr.Parts[0].LBALength
- );
- j ++; k ++;
- }
- }
+ // LBA 24
+ if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) {
+ base = mbr.Parts[i].LBAStart;
+ len = mbr.Parts[i].LBALength;
+ }
+ // LBA 48
+ else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 ) {
+ base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
+ len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
+ }
+ else {
+ Warning("Unknown partition type, Disk %i 0x%llx Part %i",
+ Disk, Addr, i);
+ return -1;
}
- // Check second entry (should be forward link)
- if( mbr.Parts[1].SystemID != 0)
+ switch(mbr.Parts[i].SystemID)
{
- if(mbr.Parts[1].Boot == 0x0 || mbr.Parts[1].Boot == 0x80 ) // LBA 28
- {
- if(mbr.Parts[1].SystemID == 0xF || mbr.Parts[1].SystemID == 0x7) {
- if(extendedLBA == 0) {
- Warning("Disk %i has twp forward link in the extended partition",
- Disk);
- break;
- }
- extendedLBA = mbr.Parts[1].LBAStart;
- }
- else
- {
- if(extendedLBA != 0) {
- Warning("Disk %i lacks a forward link in the extended partition",
- Disk);
- break;
- }
- ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, k,
- mbr.Parts[1].LBAStart, mbr.Parts[1].LBALength
- );
- j ++; k ++;
- }
-
+ case 0xF:
+ case 0x5:
+ if(link != 0) {
+ Warning("Disk %i has two forward links in the extended partition",
+ Disk);
+ return -1;
}
- else if( mbr.Parts[1].Boot == 0x1 || mbr.Parts[1].Boot == 0x81 ) // LBA 48
- {
- if(mbr.Parts[1].SystemID == 0xF || mbr.Parts[1].SystemID == 0x7) {
- if(extendedLBA == 0) {
- Warning("Disk %i has twp forward link in the extended partition",
- Disk);
- break;
- }
- extendedLBA = (mbr.Parts[1].StartHi << 16) | mbr.Parts[1].LBAStart;
- }
- else
- {
- if(extendedLBA != 0) {
- Warning("Disk %i lacks a forward link in the extended partition",
- Disk);
- break;
- }
- ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, k,
- (mbr.Parts[1].StartHi << 16) | mbr.Parts[1].LBAStart,
- (mbr.Parts[1].LengthHi << 16) | mbr.Parts[1].LBALength
- );
- j ++; k ++;
- }
+ link = base;
+ break;
+ default:
+ if(bFoundPart) {
+ Warning("Disk %i has more than one partition in the extended partition at 0x%llx",
+ Disk, Addr);
+ return -1;
}
+ bFoundPart = 1;
+ *Base = base;
+ *Length = len;
+ break;
}
}
- LEAVE('-');
+ if(!bFoundPart) {
+ Warning("No partition in extended partiton, Disk %i 0x%llx",
+ Disk, Addr);
+ return -1;
+ }
+
+ return link;
}