138 TInt r = iSession->EpocErrorCode(); |
168 TInt r = iSession->EpocErrorCode(); |
139 |
169 |
140 if (r == KErrNone) |
170 if (r == KErrNone) |
141 r = DecodePartitionInfo(); |
171 r = DecodePartitionInfo(); |
142 |
172 |
143 iDriver->PartitionInfoComplete(r == KErrNone ? r : KErrNotReady); |
173 if (!iCheckTOC) |
|
174 { |
|
175 iDriver->PartitionInfoComplete(r == KErrNone ? r : KErrNotReady); |
|
176 } |
144 } |
177 } |
145 |
178 |
146 TInt DBB5PartitionInfo::DecodePartitionInfo() |
179 TInt DBB5PartitionInfo::DecodePartitionInfo() |
147 // |
180 // |
148 // decode partition info that was read into internal buffer |
181 // Decode partition info that was read into internal buffer |
149 // |
182 // |
150 { |
183 { |
151 __KTRACE_OPT(KPBUSDRV, Kern::Printf(">Mmc:PartitionInfo()")); |
184 __KTRACE_OPT(KPBUSDRV, Kern::Printf(">Mmc:PartitionInfo()")); |
152 TUint partitionCount = iPartitionInfo->iPartitionCount = 0; |
185 TUint partitionCount = iPartitionInfo->iPartitionCount = 0; |
153 |
186 |
154 // For internal devices it is only valid to report up to 1 SWAP partition |
187 |
155 TBool foundSwap = EFalse; |
188 if (iCheckTOC) |
156 |
189 { |
157 BGAHSMMCPTN_PI_STR *partitionTable = (BGAHSMMCPTN_PI_STR*)(&iIntBuf[0]); |
190 // Try utilising the TOC (Table Of Contents) partitioning scheme |
158 |
191 const TText8* KRofsNames[KNoOfROFSPartitions] = { KTocRofs1Generic, |
159 // Verify that this is the Nokia partition table |
192 KTocRofs2Generic, |
160 if( memcompare( (TUint8*)&(partitionTable->iId[0]), sizeof(BGAHSMMCPTN_PI_ID), (TUint8*)BGAHSMMCPTN_PI_ID, sizeof(BGAHSMMCPTN_PI_ID)) == 0 ) |
193 KTocRofs3Generic, |
161 { |
194 KTocRofs4Generic, |
162 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Nokia partition structure found")); |
195 KTocRofs5Generic, |
163 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->id..............: %s", partitionTable->iId )); |
196 KTocRofs6Generic, |
164 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->sector_size.....: %d = 0x%x", partitionTable->iSector_size, partitionTable->iSector_size)); |
197 }; |
165 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->major_ver.......: %d", partitionTable->iMajor_ver)); |
198 |
166 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->minor_ver.......: %d", partitionTable->iMinor_ver)); |
199 STocItem item; |
167 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->partition_amount: %d", partitionTable->iPartition_amount)); |
200 iTocPtr = reinterpret_cast<Toc*>(&iIntBuf[0]); |
168 |
201 iTocPtr->iTocStartSector = KTocStartSector; |
169 |
202 TInt r = KErrNone; |
170 TUint8 PartitionType = 0; |
203 |
171 // Check Supported Version is present |
204 // USER Drive - Only 1 |
172 if (partitionTable->iMajor_ver <= BGAHSMMCPTN_PI_VER_MAJOR) |
205 r = iTocPtr->GetItemByName(KTocUserName, item); |
173 { |
206 if (KErrNone == r) |
174 for( TUint8 index = 0; (index < partitionTable->iPartition_amount) && (index < BGAHSMMCPTN_LAST_DRIVE); index++ ) |
207 { |
|
208 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
|
209 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeFAT16; |
|
210 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64)item.iStart; |
|
211 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64)item.iSize; |
|
212 iPartitionAttributes[partitionCount] = 0; // No Additional Attributes required. |
|
213 partitionCount++; |
|
214 } |
|
215 |
|
216 // ROM Drive |
|
217 r = iTocPtr->GetItemByName(KTocRomGeneric, item); |
|
218 if (KErrNone == r) |
|
219 { |
|
220 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%x Size = 0x%x", item.iFileName, item.iStart, item.iSize)); |
|
221 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeROM; |
|
222 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart + (KBB5HeaderSizeInSectors << KDiskSectorShift); |
|
223 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize - (KBB5HeaderSizeInSectors << KDiskSectorShift); |
|
224 partitionCount++; |
|
225 } |
|
226 |
|
227 // ROFS |
|
228 for (TUint i = 0; i < KNoOfROFSPartitions; i++) |
|
229 { |
|
230 /* Search ROFSn item */ |
|
231 r = iTocPtr->GetItemByName(KRofsNames[i], item); |
|
232 if (r == KErrNone) |
175 { |
233 { |
176 if (partitionTable->iMinor_ver >= BGAHSMMCPTN_PART_TYPE_SUPP_VER_MINOR) |
234 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
177 PartitionType = partitionTable->iPartitions[index].iPartition_type; |
235 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeRofs; |
178 else |
236 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart + (KBB5HeaderSizeInSectors << KDiskSectorShift); |
179 PartitionType = partitionTable->iPartitions[index].iPartition_id; |
237 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize - (KBB5HeaderSizeInSectors << KDiskSectorShift); |
|
238 partitionCount++; |
|
239 } |
|
240 } |
|
241 |
|
242 // CPS Drive - Only 1 |
|
243 r = iTocPtr->GetItemByName(KTocCps, item); |
|
244 if (KErrNone == r) |
|
245 { |
|
246 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
|
247 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypePartitionMagic; |
|
248 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; |
|
249 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; |
|
250 partitionCount++; |
|
251 } |
|
252 |
|
253 // CRASH Drive - Only 1 |
|
254 r = iTocPtr->GetItemByName(KTocCrashLog, item); |
|
255 if (KErrNone == r) |
|
256 { |
|
257 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
|
258 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeSymbianCrashLog; |
|
259 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; |
|
260 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; |
|
261 partitionCount++; |
|
262 } |
|
263 |
|
264 // SWAP Partition - Only 1 |
|
265 r = iTocPtr->GetItemByName(KTocSwap, item); |
|
266 if (KErrNone == r) |
|
267 { |
|
268 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
|
269 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypePagedData; |
|
270 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; |
|
271 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; |
|
272 partitionCount++; |
|
273 } |
|
274 |
|
275 #ifdef __DEBUG_PARTITIONS_ |
|
276 for (TInt i = 0; i<partitionCount; i++) |
|
277 { |
|
278 Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[i].iPartitionType); |
|
279 Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[i].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[i].iPartitionBaseAddr >> KDiskSectorShift)); |
|
280 Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[i].iPartitionLen, iPartitionInfo->iEntry[i].iPartitionLen >> KDiskSectorShift); |
|
281 Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[i]); |
|
282 Kern::Printf(" "); |
|
283 } |
|
284 #endif //__DEBUG_PARTITIONS_ |
|
285 |
|
286 iCheckTOC = EFalse; |
|
287 } |
|
288 else |
|
289 { |
|
290 // Try utilising the BB5 partitioning scheme |
|
291 BGAHSMMCPTN_PI_STR *partitionTable = (BGAHSMMCPTN_PI_STR*)(&iIntBuf[0]); |
|
292 |
|
293 // Verify that this is the Nokia partition table |
|
294 if( memcompare( (TUint8*)&(partitionTable->iId[0]), sizeof(BGAHSMMCPTN_PI_ID), (TUint8*)BGAHSMMCPTN_PI_ID, sizeof(BGAHSMMCPTN_PI_ID)) == 0 ) |
|
295 { |
|
296 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Nokia partition structure found")); |
|
297 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->id..............: %s", partitionTable->iId )); |
|
298 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->sector_size.....: %d = 0x%x", partitionTable->iSector_size, partitionTable->iSector_size)); |
|
299 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->major_ver.......: %d", partitionTable->iMajor_ver)); |
|
300 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->minor_ver.......: %d", partitionTable->iMinor_ver)); |
|
301 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->partition_amount: %d", partitionTable->iPartition_amount)); |
180 |
302 |
181 if( (partitionTable->iPartitions[index].iSize > 0) && |
303 TUint8 partitionType = 0; |
182 ( PartitionIsFAT(PartitionType) || |
304 // Check Supported Version is present |
183 PartitionIsFAT32(PartitionType) || |
305 if (partitionTable->iMajor_ver <= BGAHSMMCPTN_PI_VER_MAJOR) |
184 (KPartitionTypePagedData == PartitionType && !foundSwap) ) ) |
306 { |
185 { |
307 for( TUint8 index = 0; (index < partitionTable->iPartition_amount) && (index < BGAHSMMCPTN_LAST_DRIVE); index++ ) |
186 iPartitionInfo->iEntry[partitionCount].iPartitionType = PartitionType; |
308 { |
187 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) partitionTable->iPartitions[index].iStart_sector << KDiskSectorShift; |
309 if (partitionTable->iMinor_ver >= BGAHSMMCPTN_PART_TYPE_SUPP_VER_MINOR) |
188 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) partitionTable->iPartitions[index].iSize << KDiskSectorShift; |
310 partitionType = partitionTable->iPartitions[index].iPartition_type; |
189 iPartitionAttributes[partitionCount] = partitionTable->iPartitions[index].iPartition_attributes; |
311 else |
190 |
312 partitionType = partitionTable->iPartitions[index].iPartition_id; |
191 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Registering partition #%d:", partitionCount)); |
313 |
192 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionCount....: %d", partitionCount)); |
314 // FAT/PMM/CPS/SWAP/CORE/ROFS/CRASH |
193 __KTRACE_OPT(KPBUSDRV, Kern::Printf("startSector.......: 0x%x", partitionTable->iPartitions[index].iStart_sector )); |
315 if( (partitionTable->iPartitions[index].iSize > 0) && |
194 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr >> KDiskSectorShift))); |
316 ( PartitionIsFAT(partitionType) || |
195 __KTRACE_OPT(KPBUSDRV, Kern::Printf("size..............: 0x%lx", partitionTable->iPartitions[index].iSize )); |
317 PartitionIsFAT32(partitionType) || |
196 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionLen, iPartitionInfo->iEntry[partitionCount].iPartitionLen >> KDiskSectorShift)); |
318 (KPartitionTypeSymbianCrashLog == partitionType) || |
197 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[partitionCount].iPartitionType)); |
319 (KPartitionTypePartitionMagic == partitionType) || //CPS/PMM |
198 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[partitionCount])); |
320 (KPartitionTypeRofs == partitionType) || |
199 __KTRACE_OPT(KPBUSDRV, Kern::Printf(" ")); |
321 (KPartitionTypeEmpty == partitionType) || |
200 |
322 (KPartitionTypeROM == partitionType) || |
201 if(KPartitionTypePagedData == PartitionType) |
323 (KPartitionTypePagedData == partitionType) ) ) |
202 { |
324 { |
203 foundSwap = ETrue; |
325 iPartitionInfo->iEntry[partitionCount].iPartitionType = partitionType; |
|
326 iPartitionAttributes[partitionCount] = partitionTable->iPartitions[index].iPartition_attributes; |
|
327 |
|
328 // ROM/ROFS partitions have a BB5 checksum header that must be offset for the Symbian OS. |
|
329 const TUint32 KstartOffset = ((KPartitionTypeROM == partitionType) || (KPartitionTypeRofs == partitionType) || (KPartitionTypeEmpty == partitionType)) ? KBB5HeaderSizeInSectors : 0; |
|
330 |
|
331 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) ((partitionTable->iPartitions[index].iStart_sector + KstartOffset) << KDiskSectorShift); |
|
332 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) ((partitionTable->iPartitions[index].iSize - KstartOffset) << KDiskSectorShift); |
|
333 |
|
334 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Registering partition #%d:", partitionCount)); |
|
335 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionCount....: %d", partitionCount)); |
|
336 __KTRACE_OPT(KPBUSDRV, Kern::Printf("startSector.......: 0x%x", partitionTable->iPartitions[index].iStart_sector )); |
|
337 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr >> KDiskSectorShift))); |
|
338 __KTRACE_OPT(KPBUSDRV, Kern::Printf("size..............: 0x%lx", partitionTable->iPartitions[index].iSize )); |
|
339 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionLen, iPartitionInfo->iEntry[partitionCount].iPartitionLen >> KDiskSectorShift)); |
|
340 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[partitionCount].iPartitionType)); |
|
341 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[partitionCount])); |
|
342 __KTRACE_OPT(KPBUSDRV, Kern::Printf(" ")); |
|
343 |
|
344 partitionCount++; |
204 } |
345 } |
205 |
|
206 partitionCount++; |
|
207 } |
346 } |
208 } |
347 } |
209 } |
348 } |
210 } |
349 else |
211 |
350 { |
|
351 __KTRACE_OPT(KPBUSDRV, Kern::Printf("BGAHSMMC signature not found - try TOC layout")); |
|
352 iCheckTOC = ETrue; |
|
353 |
|
354 TInt r = ReadPartition(KTocStartSector); |
|
355 return r; |
|
356 } |
|
357 } |
|
358 |
|
359 |
212 // Validate partition address boundaries |
360 // Validate partition address boundaries |
213 if(partitionCount == 0) |
361 if(partitionCount == 0) |
214 { |
362 { |
215 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: No supported partitions found!")); |
363 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: No supported partitions found!")); |
216 return KErrCorrupt; |
364 return KErrCorrupt; |
217 } |
365 } |
|
366 #ifdef __DEBUG_CHECK_PARTITION_ |
218 else |
367 else |
219 { |
368 { |
220 // at least one entry for a supported partition found |
369 // at least one entry for a supported partition found |
221 const TInt64 deviceSize = iCard->DeviceSize64(); |
370 const TInt64 deviceSize = iCard->DeviceSize64(); |
222 TPartitionEntry& part = iPartitionInfo->iEntry[partitionCount - 1]; |
371 TPartitionEntry& part = iPartitionInfo->iEntry[partitionCount - 1]; |