86f61bb96009fc200daed41f2c7e88a71f7647b4
[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 // == GLOBALS ===
11
12 // === CODE ===
13 /**
14  * \fn void ATA_ParseMBR(int Disk)
15  */
16 void ATA_ParseMBR(int Disk)
17 {
18          int    i, j = 0, k = 4;
19         tMBR    mbr;
20         Uint64  extendedLBA;
21         
22         ENTER("iDisk", Disk);
23         
24         // Read Boot Sector
25         ATA_ReadDMA( Disk, 0, 1, &mbr );
26         
27         // Count Partitions
28         gATA_Disks[Disk].NumPartitions = 0;
29         extendedLBA = 0;
30         for( i = 0; i < 4; i ++ )
31         {
32                 if( mbr.Parts[i].SystemID == 0 )        continue;
33                 if(
34                         mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80   // LBA 28
35                 ||      mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81   // LBA 48
36                         )
37                 {
38                         if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
39                                 LOG("Extended Partition");
40                                 if(extendedLBA != 0) {
41                                         Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
42                                         continue;
43                                 }
44                                 extendedLBA = mbr.Parts[i].LBAStart;
45                                 continue;
46                         }
47                         LOG("Primary Partition");
48                         
49                         gATA_Disks[Disk].NumPartitions ++;
50                         continue;
51                 }
52                 // Invalid Partition, so don't count it
53         }
54         while(extendedLBA != 0)
55         {
56                 if( ATA_ReadDMA( Disk, extendedLBA, 1, &mbr ) != 0 )
57                         break;  // Stop on Errors
58                 
59                 extendedLBA = 0;
60                 
61                 if( mbr.Parts[0].SystemID == 0 )        continue;
62                 if(     mbr.Parts[0].Boot == 0x0 || mbr.Parts[0].Boot == 0x80   // LBA 28
63                 ||      mbr.Parts[0].Boot == 0x1 || mbr.Parts[0].Boot == 0x81   // LBA 48
64                         )
65                 {
66                         if(mbr.Parts[0].SystemID == 0xF || mbr.Parts[0].SystemID == 0x7)
67                                 extendedLBA = mbr.Parts[0].LBAStart;
68                         else
69                                 gATA_Disks[Disk].NumPartitions ++;
70                 }
71                 
72                 if( mbr.Parts[1].SystemID == 0 )        continue;
73                 if(     mbr.Parts[1].Boot == 0x0 || mbr.Parts[1].Boot == 0x80   // LBA 28
74                 ||      mbr.Parts[1].Boot == 0x1 || mbr.Parts[1].Boot == 0x81   // LBA 48
75                         )
76                 {
77                         if(mbr.Parts[1].SystemID == 0xF || mbr.Parts[1].SystemID == 0x7) {
78                                 if(extendedLBA == 0) {
79                                         Warning("Disk %i has twp forward link in the extended partition",
80                                                 Disk);
81                                         break;
82                                 }
83                                 extendedLBA = mbr.Parts[1].LBAStart;
84                         }
85                         else {
86                                 if(extendedLBA != 0) {
87                                         Warning("Disk %i lacks a forward link in the extended partition",
88                                                 Disk);
89                                         break;
90                                 }
91                                 gATA_Disks[Disk].NumPartitions ++;
92                         }
93                 }
94         }
95         LOG("gATA_Disks[Disk].NumPartitions = %i", gATA_Disks[Disk].NumPartitions);
96         
97         // Create patition array
98         gATA_Disks[Disk].Partitions = malloc( gATA_Disks[Disk].NumPartitions * sizeof(tATA_Partition) );
99         
100         // --- Fill Partition Info ---
101         extendedLBA = 0;
102         for( i = 0; i < 4; i ++ )
103         {
104                 Log("mbr.Parts[%i].SystemID = 0x%02x", i, mbr.Parts[i].SystemID);
105                 if( mbr.Parts[i].SystemID == 0 )        continue;
106                 if(     mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) // LBA 28
107                 {
108                         if( mbr.Parts[1].SystemID == 0xF || mbr.Parts[1].SystemID == 5 ) {
109                                 if(extendedLBA != 0) {
110                                         Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
111                                         continue;
112                                 }
113                                 extendedLBA = mbr.Parts[1].LBAStart;
114                                 continue;
115                         }
116                         // Create Partition
117                         ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, i,
118                                 mbr.Parts[i].LBAStart, mbr.Parts[i].LBALength
119                                 );
120                         j ++;
121                         continue;
122                 }
123                 if(     mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 ) // LBA 48
124                 {
125                         if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
126                                 if(extendedLBA != 0) {
127                                         Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
128                                         continue;
129                                 }
130                                 extendedLBA = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
131                                 continue;
132                         }
133                         ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, i,
134                                 (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart,
135                                 (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength
136                                 );
137                         j ++;
138                 }
139                 // Invalid Partition, so don't count it
140         }
141         // Scan extended partition
142         while(extendedLBA != 0)
143         {
144                 if( ATA_ReadDMA( Disk, extendedLBA, 1, &mbr ) != 0 )
145                         break;  // Stop on Errors
146                 
147                 extendedLBA = 0;
148                 
149                 // Check first entry (should be partition)
150                 if( mbr.Parts[0].SystemID != 0)
151                 {
152                         if( mbr.Parts[0].Boot == 0x0 || mbr.Parts[0].Boot == 0x80 )     // LBA 28
153                         {
154                                 // Forward Link to next Extended partition entry
155                                 if(mbr.Parts[0].SystemID == 0xF || mbr.Parts[0].SystemID == 0x7)
156                                         extendedLBA = mbr.Parts[0].LBAStart;
157                                 else {
158                                         ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, k,
159                                                 mbr.Parts[0].LBAStart, mbr.Parts[0].LBALength
160                                                 );
161                                         j ++;   k ++;
162                                 }
163                         }
164                         else if( mbr.Parts[0].Boot == 0x1 || mbr.Parts[0].Boot == 0x81 )        // LBA 48
165                         {
166                                 if(mbr.Parts[0].SystemID == 0xF || mbr.Parts[0].SystemID == 0x7)
167                                         extendedLBA = (mbr.Parts[0].StartHi << 16) | mbr.Parts[0].LBAStart;
168                                 else {
169                                         ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, k,
170                                                 (mbr.Parts[0].StartHi << 16) | mbr.Parts[0].LBAStart,
171                                                 (mbr.Parts[0].LengthHi << 16) | mbr.Parts[0].LBALength
172                                                 );
173                                         j ++;   k ++;
174                                 }
175                         }
176                 }
177                 
178                 // Check second entry (should be forward link)
179                 if( mbr.Parts[1].SystemID != 0)
180                 {
181                         if(mbr.Parts[1].Boot == 0x0 || mbr.Parts[1].Boot == 0x80 )      // LBA 28
182                         {
183                                 if(mbr.Parts[1].SystemID == 0xF || mbr.Parts[1].SystemID == 0x7) {
184                                         if(extendedLBA == 0) {
185                                                 Warning("Disk %i has twp forward link in the extended partition",
186                                                         Disk);
187                                                 break;
188                                         }
189                                         extendedLBA = mbr.Parts[1].LBAStart;
190                                 }
191                                 else
192                                 {
193                                         if(extendedLBA != 0) {
194                                                 Warning("Disk %i lacks a forward link in the extended partition",
195                                                         Disk);
196                                                 break;
197                                         }
198                                         ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, k,
199                                                 mbr.Parts[1].LBAStart, mbr.Parts[1].LBALength
200                                                 );
201                                         j ++;   k ++;
202                                 }
203                                 
204                         }
205                         else if( mbr.Parts[1].Boot == 0x1 || mbr.Parts[1].Boot == 0x81 )        // LBA 48
206                         {
207                                 if(mbr.Parts[1].SystemID == 0xF || mbr.Parts[1].SystemID == 0x7) {
208                                         if(extendedLBA == 0) {
209                                                 Warning("Disk %i has twp forward link in the extended partition",
210                                                         Disk);
211                                                 break;
212                                         }
213                                         extendedLBA = (mbr.Parts[1].StartHi << 16) | mbr.Parts[1].LBAStart;
214                                 }
215                                 else
216                                 {
217                                         if(extendedLBA != 0) {
218                                                 Warning("Disk %i lacks a forward link in the extended partition",
219                                                         Disk);
220                                                 break;
221                                         }
222                                         ATA_int_MakePartition( &gATA_Disks[Disk].Partitions[j], Disk, k,
223                                                 (mbr.Parts[1].StartHi << 16) | mbr.Parts[1].LBAStart,
224                                                 (mbr.Parts[1].LengthHi << 16) | mbr.Parts[1].LBALength
225                                                 );
226                                         j ++;   k ++;
227                                 }
228                         }
229                 }
230         }
231         
232         LEAVE('-');
233 }

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