I really need to learn to compile test before commiting
[tpg/acess2.git] / Modules / ATA / mbr.c
1 /*
2  * Acess2 IDE Harddisk Driver
3  * - MBR Parsing Code
4  * mbr.c
5  */
6 #define DEBUG   0
7 #include <acess.h>
8 #include "common.h"
9
10 // === PROTOTYPES ===
11 Uint64  ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length);
12
13 // === GLOBALS ===
14
15 // === CODE ===
16 /**
17  * \fn void ATA_ParseMBR(int Disk)
18  */
19 void ATA_ParseMBR(int Disk)
20 {
21          int    i, j = 0, k = 4;
22         tMBR    mbr;
23         Uint64  extendedLBA;
24         Uint64  base, len;
25         
26         ENTER("iDisk", Disk);
27         
28         // Read Boot Sector
29         ATA_ReadDMA( Disk, 0, 1, &mbr );
30         
31         // Count Partitions
32         gATA_Disks[Disk].NumPartitions = 0;
33         extendedLBA = 0;
34         for( i = 0; i < 4; i ++ )
35         {
36                 if( mbr.Parts[i].SystemID == 0 )        continue;
37                 if(
38                         mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80   // LBA 28
39                 ||      mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81   // LBA 48
40                         )
41                 {
42                         if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
43                                 LOG("Extended Partition");
44                                 if(extendedLBA != 0) {
45                                         Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
46                                         continue;
47                                 }
48                                 extendedLBA = mbr.Parts[i].LBAStart;
49                                 continue;
50                         }
51                         LOG("Primary Partition");
52                         
53                         gATA_Disks[Disk].NumPartitions ++;
54                         continue;
55                 }
56                 // Invalid Partition, so don't count it
57         }
58         while(extendedLBA != 0)
59         {
60                 extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
61                 if( extendedLBA == -1 ) return ;
62                 gATA_Disks[Disk].NumPartitions ++;
63         }
64         LOG("gATA_Disks[Disk].NumPartitions = %i", gATA_Disks[Disk].NumPartitions);
65         
66         // Create patition array
67         gATA_Disks[Disk].Partitions = malloc( gATA_Disks[Disk].NumPartitions * sizeof(tATA_Partition) );
68         
69         // --- Fill Partition Info ---
70         extendedLBA = 0;
71         for( j = 0, i = 0; i < 4; i ++ )
72         {
73                 Log("mbr.Parts[%i].SystemID = 0x%02x", i, mbr.Parts[i].SystemID);
74                 if( mbr.Parts[i].SystemID == 0 )        continue;
75                 if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 )     // LBA 28
76                 {
77                         base = mbr.Parts[i].LBAStart;
78                         len = mbr.Parts[i].LBALength;
79                 }
80                 else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 )        // LBA 58
81                 {
82                         base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
83                         len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
84                 }
85                 else
86                         continue;
87                 
88                 if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
89                         if(extendedLBA != 0) {
90                                 Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
91                                 continue;
92                         }
93                         extendedLBA = base;
94                         continue;
95                 }
96                 // Create Partition
97                 ATA_int_MakePartition(
98                         &gATA_Disks[Disk].Partitions[j], Disk, j,
99                         base, len
100                         );
101                 j ++;
102                 
103         }
104         // Scan extended partitions
105         while(extendedLBA != 0)
106         {
107                 extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
108                 ATA_int_MakePartition(
109                         &gATA_Disks[Disk].Partitions[j], Disk, k, base, len
110                         );
111         }
112         
113         LEAVE('-');
114 }
115
116 /**
117  * \brief Reads an extended partition
118  * \return LBA of next Extended, -1 on error, 0 for last
119  */
120 Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length)
121 {
122         Uint64  link = 0;
123          int    bFoundPart = 0;;
124          int    i;
125         tMBR    mbr;
126         Uint64  base, len;
127         
128         if( ATA_ReadDMA( Disk, Addr, 1, &mbr ) != 0 )
129                 return -1;      // Stop on Errors
130         
131         
132         for( i = 0; i < 4; i ++ )
133         {
134                 if( mbr.Parts[i].SystemID == 0 )        continue;
135                 
136                 // LBA 24
137                 if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) {
138                         base = mbr.Parts[i].LBAStart;
139                         len = mbr.Parts[i].LBALength;
140                 }
141                 // LBA 48
142                 else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 ) {
143                         base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
144                         len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
145                 }
146                 else {
147                         Warning("Unknown partition type, Disk %i 0x%llx Part %i",
148                                 Disk, Addr, i);
149                         return -1;
150                 }
151                 
152                 switch(mbr.Parts[i].SystemID)
153                 {
154                 case 0xF:
155                 case 0x5:
156                         if(link != 0) {
157                                 Warning("Disk %i has two forward links in the extended partition",
158                                         Disk);
159                                 return -1;
160                         }
161                         link = base;
162                         break;
163                 default:
164                         if(bFoundPart) {
165                                 Warning("Disk %i has more than one partition in the extended partition at 0x%llx",
166                                         Disk, Addr);
167                                 return -1;
168                         }
169                         bFoundPart = 1;
170                         *Base = base;
171                         *Length = len;
172                         break;
173                 }
174         }
175         
176         if(!bFoundPart) {
177                 Warning("No partition in extended partiton, Disk %i 0x%llx",
178                         Disk, Addr);
179                 return -1;
180         }
181         
182         return link;
183 }

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