Altered & Renamed LookupString, Added DrvUtil_SetIdent
[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(     mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80   // LBA 28
38                 ||      mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81   // LBA 48
39                         )
40                 {
41                         if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
42                                 LOG("Extended Partition");
43                                 if(extendedLBA != 0) {
44                                         Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
45                                         continue;
46                                 }
47                                 extendedLBA = mbr.Parts[i].LBAStart;
48                                 continue;
49                         }
50                         LOG("Primary Partition");
51                         
52                         gATA_Disks[Disk].NumPartitions ++;
53                         continue;
54                 }
55                 // Invalid Partition, so don't count it
56         }
57         while(extendedLBA != 0)
58         {
59                 extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
60                 if( extendedLBA == -1 ) return ;
61                 gATA_Disks[Disk].NumPartitions ++;
62         }
63         LOG("gATA_Disks[Disk].NumPartitions = %i", gATA_Disks[Disk].NumPartitions);
64         
65         // Create patition array
66         gATA_Disks[Disk].Partitions = malloc( gATA_Disks[Disk].NumPartitions * sizeof(tATA_Partition) );
67         
68         // --- Fill Partition Info ---
69         extendedLBA = 0;
70         for( j = 0, i = 0; i < 4; i ++ )
71         {
72                 Log("mbr.Parts[%i].SystemID = 0x%02x", i, mbr.Parts[i].SystemID);
73                 if( mbr.Parts[i].SystemID == 0 )        continue;
74                 if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 )     // LBA 28
75                 {
76                         base = mbr.Parts[i].LBAStart;
77                         len = mbr.Parts[i].LBALength;
78                 }
79                 else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 )        // LBA 58
80                 {
81                         base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
82                         len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
83                 }
84                 else
85                         continue;
86                 
87                 if( mbr.Parts[i].SystemID == 0xF || mbr.Parts[i].SystemID == 5 ) {
88                         if(extendedLBA != 0) {
89                                 Warning("Disk %i has multiple extended partitions, ignoring rest", Disk);
90                                 continue;
91                         }
92                         extendedLBA = base;
93                         continue;
94                 }
95                 // Create Partition
96                 ATA_int_MakePartition(
97                         &gATA_Disks[Disk].Partitions[j], Disk, j,
98                         base, len
99                         );
100                 j ++;
101                 
102         }
103         // Scan extended partitions
104         while(extendedLBA != 0)
105         {
106                 extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len);
107                 ATA_int_MakePartition(
108                         &gATA_Disks[Disk].Partitions[j], Disk, k, base, len
109                         );
110         }
111         
112         LEAVE('-');
113 }
114
115 /**
116  * \brief Reads an extended partition
117  * \return LBA of next Extended, -1 on error, 0 for last
118  */
119 Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length)
120 {
121         Uint64  link = 0;
122          int    bFoundPart = 0;;
123          int    i;
124         tMBR    mbr;
125         Uint64  base, len;
126         
127         if( ATA_ReadDMA( Disk, Addr, 1, &mbr ) != 0 )
128                 return -1;      // Stop on Errors
129         
130         
131         for( i = 0; i < 4; i ++ )
132         {
133                 if( mbr.Parts[i].SystemID == 0 )        continue;
134                 
135                 // LBA 24
136                 if( mbr.Parts[i].Boot == 0x0 || mbr.Parts[i].Boot == 0x80 ) {
137                         base = mbr.Parts[i].LBAStart;
138                         len = mbr.Parts[i].LBALength;
139                 }
140                 // LBA 48
141                 else if( mbr.Parts[i].Boot == 0x1 || mbr.Parts[i].Boot == 0x81 ) {
142                         base = (mbr.Parts[i].StartHi << 16) | mbr.Parts[i].LBAStart;
143                         len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength;
144                 }
145                 else {
146                         Warning("Unknown partition type, Disk %i 0x%llx Part %i",
147                                 Disk, Addr, i);
148                         return -1;
149                 }
150                 
151                 switch(mbr.Parts[i].SystemID)
152                 {
153                 case 0xF:
154                 case 0x5:
155                         if(link != 0) {
156                                 Warning("Disk %i has two forward links in the extended partition",
157                                         Disk);
158                                 return -1;
159                         }
160                         link = base;
161                         break;
162                 default:
163                         if(bFoundPart) {
164                                 Warning("Disk %i has more than one partition in the extended partition at 0x%llx",
165                                         Disk, Addr);
166                                 return -1;
167                         }
168                         bFoundPart = 1;
169                         *Base = base;
170                         *Length = len;
171                         break;
172                 }
173         }
174         
175         if(!bFoundPart) {
176                 Warning("No partition in extended partiton, Disk %i 0x%llx",
177                         Disk, Addr);
178                 return -1;
179         }
180         
181         return link;
182 }

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