diff -r c1f20ce4abcf -r 3e88ff8f41d5 kernel/eka/drivers/medmmc/bgahsmmcptn.cpp --- a/kernel/eka/drivers/medmmc/bgahsmmcptn.cpp Tue Aug 31 16:34:26 2010 +0300 +++ b/kernel/eka/drivers/medmmc/bgahsmmcptn.cpp Wed Sep 01 12:34:56 2010 +0100 @@ -17,10 +17,9 @@ #include #include "bgahsmmcptn.h" -#include "toc.h" -//#define __DEBUG_PARTITIONS_ -//#define __DEBUG_CHECK_PARTITION_ -const TInt KDiskSectorShift = 9; + +const TInt KDiskSectorShift = 9; +const TUint32 KPIOffsetFromMediaEnd = 1; class DBB5PartitionInfo : public DEMMCPartitionInfo { @@ -37,7 +36,6 @@ void SetPartitionEntry(TPartitionEntry* aEntry, TUint aFirstSector, TUint aNumSectors); private: - virtual TInt ReadPartition(TUint32 aPtOffset); static void SessionEndCallBack(TAny* aSelf); void DoSessionEndCallBack(); virtual TInt DecodePartitionInfo(); @@ -51,13 +49,10 @@ TMMCard* iCard; TUint8* iIntBuf; TUint32 iPartitionAttributes[KMaxLocalDrives]; - TBool iCheckTOC; - Toc* iTocPtr; }; DBB5PartitionInfo::DBB5PartitionInfo() - : iSessionEndCallBack(DBB5PartitionInfo::SessionEndCallBack, this), - iCheckTOC(EFalse) + : iSessionEndCallBack(DBB5PartitionInfo::SessionEndCallBack, this) { } @@ -96,19 +91,13 @@ iPartitionInfo = &aInfo; iCallBack = aCallBack; - // Preferred partition scheme is BB5, which is located in the last block of the media. - const TUint32 ptiOffset = (I64LOW(iCard->DeviceSize64() >> KDiskSectorShift)) - KPIOffsetFromMediaEnd; - return ReadPartition(ptiOffset); - } - -TInt DBB5PartitionInfo::ReadPartition(TUint32 aPtOffset) - { // If media driver is persistent (see EMediaDriverPersistent) // the card may have changed since last power down, so reset CID iSession->SetCard(iCard); - iSession->SetupCIMReadBlock(aPtOffset, iIntBuf); - + const TUint32 ptiOffset = (I64LOW(iCard->DeviceSize64() >> KDiskSectorShift)) - KPIOffsetFromMediaEnd; + iSession->SetupCIMReadBlock(ptiOffset, iIntBuf); + TInt r = iDriver->InCritical(); if (r == KErrNone) r = iSession->Engage(); @@ -128,25 +117,6 @@ Info().iFileSystemId = KDriveFileNone; Info().iDriveAtt |= KDriveAttHidden; } - else if (aDrive.iPartitionType == KPartitionTypeRofs) - { - Info().iFileSystemId = KDriveFileSysROFS; - Info().iMediaAtt &= ~KMediaAttFormattable; - Info().iMediaAtt |= KMediaAttWriteProtected; - } - else if ((aDrive.iPartitionType == KPartitionTypeROM) || - (aDrive.iPartitionType == KPartitionTypeEmpty)) - { - Info().iFileSystemId = KDriveFileNone; - Info().iMediaAtt &= ~KMediaAttFormattable; - Info().iMediaAtt |= KMediaAttWriteProtected; - } - else if ((aDrive.iPartitionType == KPartitionTypePartitionMagic) || //CPS/PMM - (aDrive.iPartitionType == KPartitionTypeSymbianCrashLog)) - { - Info().iFileSystemId = KDriveFileNone; - Info().iMediaAtt |= KMediaAttFormattable; - } else if ( PartitionIsFAT(aDrive.iPartitionType) || PartitionIsFAT32(aDrive.iPartitionType) ) { Info().iDriveAtt |= iPartitionAttributes[aDrive.iPartitionNumber]; @@ -170,200 +140,81 @@ if (r == KErrNone) r = DecodePartitionInfo(); - if (!iCheckTOC) - { - iDriver->PartitionInfoComplete(r == KErrNone ? r : KErrNotReady); - } + iDriver->PartitionInfoComplete(r == KErrNone ? r : KErrNotReady); } TInt DBB5PartitionInfo::DecodePartitionInfo() // -// Decode partition info that was read into internal buffer +// decode partition info that was read into internal buffer // { __KTRACE_OPT(KPBUSDRV, Kern::Printf(">Mmc:PartitionInfo()")); TUint partitionCount = iPartitionInfo->iPartitionCount = 0; - - if (iCheckTOC) - { - // Try utilising the TOC (Table Of Contents) partitioning scheme - const TText8* KRofsNames[KNoOfROFSPartitions] = { KTocRofs1Generic, - KTocRofs2Generic, - KTocRofs3Generic, - KTocRofs4Generic, - KTocRofs5Generic, - KTocRofs6Generic, - }; - - STocItem item; - iTocPtr = reinterpret_cast(&iIntBuf[0]); - iTocPtr->iTocStartSector = KTocStartSector; - TInt r = KErrNone; + // For internal devices it is only valid to report up to 1 SWAP partition + TBool foundSwap = EFalse; -// USER Drive - Only 1 - r = iTocPtr->GetItemByName(KTocUserName, item); - if (KErrNone == r) - { - __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); - iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeFAT16; - iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64)item.iStart; - iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64)item.iSize; - iPartitionAttributes[partitionCount] = 0; // No Additional Attributes required. - partitionCount++; - } - -// ROM Drive - r = iTocPtr->GetItemByName(KTocRomGeneric, item); - if (KErrNone == r) - { - __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%x Size = 0x%x", item.iFileName, item.iStart, item.iSize)); - iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeROM; - iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart + (KBB5HeaderSizeInSectors << KDiskSectorShift); - iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize - (KBB5HeaderSizeInSectors << KDiskSectorShift); - partitionCount++; - } - -// ROFS - for (TUint i = 0; i < KNoOfROFSPartitions; i++) - { - /* Search ROFSn item */ - r = iTocPtr->GetItemByName(KRofsNames[i], item); - if (r == KErrNone) - { - __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); - iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeRofs; - iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart + (KBB5HeaderSizeInSectors << KDiskSectorShift); - iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize - (KBB5HeaderSizeInSectors << KDiskSectorShift); - partitionCount++; - } - } + BGAHSMMCPTN_PI_STR *partitionTable = (BGAHSMMCPTN_PI_STR*)(&iIntBuf[0]); -// CPS Drive - Only 1 - r = iTocPtr->GetItemByName(KTocCps, item); - if (KErrNone == r) - { - __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); - iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypePartitionMagic; - iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; - iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; - partitionCount++; - } - -// CRASH Drive - Only 1 - r = iTocPtr->GetItemByName(KTocCrashLog, item); - if (KErrNone == r) - { - __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); - iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeSymbianCrashLog; - iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; - iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; - partitionCount++; - } - -// SWAP Partition - Only 1 - r = iTocPtr->GetItemByName(KTocSwap, item); - if (KErrNone == r) - { - __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); - iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypePagedData; - iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; - iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; - partitionCount++; - } - -#ifdef __DEBUG_PARTITIONS_ - for (TInt i = 0; iiEntry[i].iPartitionType); - Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[i].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[i].iPartitionBaseAddr >> KDiskSectorShift)); - Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[i].iPartitionLen, iPartitionInfo->iEntry[i].iPartitionLen >> KDiskSectorShift); - Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[i]); - Kern::Printf(" "); - } -#endif //__DEBUG_PARTITIONS_ - - iCheckTOC = EFalse; - } - else - { - // Try utilising the BB5 partitioning scheme - BGAHSMMCPTN_PI_STR *partitionTable = (BGAHSMMCPTN_PI_STR*)(&iIntBuf[0]); + // Verify that this is the Nokia partition table + if( memcompare( (TUint8*)&(partitionTable->iId[0]), sizeof(BGAHSMMCPTN_PI_ID), (TUint8*)BGAHSMMCPTN_PI_ID, sizeof(BGAHSMMCPTN_PI_ID)) == 0 ) + { + __KTRACE_OPT(KPBUSDRV, Kern::Printf("Nokia partition structure found")); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->id..............: %s", partitionTable->iId )); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->sector_size.....: %d = 0x%x", partitionTable->iSector_size, partitionTable->iSector_size)); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->major_ver.......: %d", partitionTable->iMajor_ver)); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->minor_ver.......: %d", partitionTable->iMinor_ver)); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->partition_amount: %d", partitionTable->iPartition_amount)); + + + TUint8 PartitionType = 0; + // Check Supported Version is present + if (partitionTable->iMajor_ver <= BGAHSMMCPTN_PI_VER_MAJOR) + { + for( TUint8 index = 0; (index < partitionTable->iPartition_amount) && (index < BGAHSMMCPTN_LAST_DRIVE); index++ ) + { + if (partitionTable->iMinor_ver >= BGAHSMMCPTN_PART_TYPE_SUPP_VER_MINOR) + PartitionType = partitionTable->iPartitions[index].iPartition_type; + else + PartitionType = partitionTable->iPartitions[index].iPartition_id; + + if( (partitionTable->iPartitions[index].iSize > 0) && + ( PartitionIsFAT(PartitionType) || + PartitionIsFAT32(PartitionType) || + (KPartitionTypePagedData == PartitionType && !foundSwap) ) ) + { + iPartitionInfo->iEntry[partitionCount].iPartitionType = PartitionType; + iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) partitionTable->iPartitions[index].iStart_sector << KDiskSectorShift; + iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) partitionTable->iPartitions[index].iSize << KDiskSectorShift; + iPartitionAttributes[partitionCount] = partitionTable->iPartitions[index].iPartition_attributes; - // Verify that this is the Nokia partition table - if( memcompare( (TUint8*)&(partitionTable->iId[0]), sizeof(BGAHSMMCPTN_PI_ID), (TUint8*)BGAHSMMCPTN_PI_ID, sizeof(BGAHSMMCPTN_PI_ID)) == 0 ) - { - __KTRACE_OPT(KPBUSDRV, Kern::Printf("Nokia partition structure found")); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->id..............: %s", partitionTable->iId )); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->sector_size.....: %d = 0x%x", partitionTable->iSector_size, partitionTable->iSector_size)); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->major_ver.......: %d", partitionTable->iMajor_ver)); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->minor_ver.......: %d", partitionTable->iMinor_ver)); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->partition_amount: %d", partitionTable->iPartition_amount)); - - TUint8 partitionType = 0; - // Check Supported Version is present - if (partitionTable->iMajor_ver <= BGAHSMMCPTN_PI_VER_MAJOR) - { - for( TUint8 index = 0; (index < partitionTable->iPartition_amount) && (index < BGAHSMMCPTN_LAST_DRIVE); index++ ) - { - if (partitionTable->iMinor_ver >= BGAHSMMCPTN_PART_TYPE_SUPP_VER_MINOR) - partitionType = partitionTable->iPartitions[index].iPartition_type; - else - partitionType = partitionTable->iPartitions[index].iPartition_id; - - // FAT/PMM/CPS/SWAP/CORE/ROFS/CRASH - if( (partitionTable->iPartitions[index].iSize > 0) && - ( PartitionIsFAT(partitionType) || - PartitionIsFAT32(partitionType) || - (KPartitionTypeSymbianCrashLog == partitionType) || - (KPartitionTypePartitionMagic == partitionType) || //CPS/PMM - (KPartitionTypeRofs == partitionType) || - (KPartitionTypeEmpty == partitionType) || - (KPartitionTypeROM == partitionType) || - (KPartitionTypePagedData == partitionType) ) ) - { - iPartitionInfo->iEntry[partitionCount].iPartitionType = partitionType; - iPartitionAttributes[partitionCount] = partitionTable->iPartitions[index].iPartition_attributes; - - // ROM/ROFS partitions have a BB5 checksum header that must be offset for the Symbian OS. - const TUint32 KstartOffset = ((KPartitionTypeROM == partitionType) || (KPartitionTypeRofs == partitionType) || (KPartitionTypeEmpty == partitionType)) ? KBB5HeaderSizeInSectors : 0; - - iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) ((partitionTable->iPartitions[index].iStart_sector + KstartOffset) << KDiskSectorShift); - iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) ((partitionTable->iPartitions[index].iSize - KstartOffset) << KDiskSectorShift); - - __KTRACE_OPT(KPBUSDRV, Kern::Printf("Registering partition #%d:", partitionCount)); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionCount....: %d", partitionCount)); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("startSector.......: 0x%x", partitionTable->iPartitions[index].iStart_sector )); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr >> KDiskSectorShift))); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("size..............: 0x%lx", partitionTable->iPartitions[index].iSize )); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionLen, iPartitionInfo->iEntry[partitionCount].iPartitionLen >> KDiskSectorShift)); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[partitionCount].iPartitionType)); - __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[partitionCount])); - __KTRACE_OPT(KPBUSDRV, Kern::Printf(" ")); - - partitionCount++; + __KTRACE_OPT(KPBUSDRV, Kern::Printf("Registering partition #%d:", partitionCount)); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionCount....: %d", partitionCount)); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("startSector.......: 0x%x", partitionTable->iPartitions[index].iStart_sector )); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr >> KDiskSectorShift))); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("size..............: 0x%lx", partitionTable->iPartitions[index].iSize )); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionLen, iPartitionInfo->iEntry[partitionCount].iPartitionLen >> KDiskSectorShift)); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[partitionCount].iPartitionType)); + __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[partitionCount])); + __KTRACE_OPT(KPBUSDRV, Kern::Printf(" ")); + + if(KPartitionTypePagedData == PartitionType) + { + foundSwap = ETrue; } + + partitionCount++; } - } - } - else - { - __KTRACE_OPT(KPBUSDRV, Kern::Printf("BGAHSMMC signature not found - try TOC layout")); - iCheckTOC = ETrue; - - TInt r = ReadPartition(KTocStartSector); - return r; - } - } - - + } + } + } + // Validate partition address boundaries if(partitionCount == 0) { __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: No supported partitions found!")); return KErrCorrupt; } -#ifdef __DEBUG_CHECK_PARTITION_ else { // at least one entry for a supported partition found @@ -391,7 +242,6 @@ } } } -#endif // _DEBUG_CHECK_PARTITION_ iPartitionInfo->iPartitionCount = partitionCount; iPartitionInfo->iMediaSizeInBytes = iCard->DeviceSize64();