80 while (minSectorsPerCluster>iSectorsPerCluster) |
80 while (minSectorsPerCluster>iSectorsPerCluster) |
81 iSectorsPerCluster<<=1; |
81 iSectorsPerCluster<<=1; |
82 iSectorsPerFat=MaxFat16Sectors(); |
82 iSectorsPerFat=MaxFat16Sectors(); |
83 } |
83 } |
84 |
84 |
85 // Ensure cluster size is a multiple of the block size |
85 const TFatType fatType = SuggestFatType(); |
86 TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2; |
86 |
87 __PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors); |
87 // Ensure cluster size is a multiple of the block size |
88 ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors)); |
88 TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2; |
89 if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors)) |
89 __PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors); |
90 { |
90 ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors)); |
91 __PRINT1(_L("iSectorsPerCluster (old): %d"),iSectorsPerCluster); |
91 if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors)) |
92 AdjustClusterSize(blockSizeInSectors); |
92 { |
93 __PRINT1(_L("iSectorsPerCluster (new): %d"),iSectorsPerCluster); |
93 __PRINT1(_L("iSectorsPerCluster (old): %d"),iSectorsPerCluster); |
94 } |
94 AdjustClusterSize(blockSizeInSectors); |
95 |
95 __PRINT1(_L("iSectorsPerCluster (new): %d"),iSectorsPerCluster); |
96 // Align first data sector on an erase block boundary if |
96 } |
97 // (1) the iEraseBlockSize is specified |
97 |
98 // (2) the start of the partition is already aligned to an erase block boundary, |
98 |
99 // i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize |
99 for (; iSectorsPerCluster>1; iSectorsPerCluster>>= 1) |
100 __PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors); |
100 { |
101 TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2; |
101 // Align first data sector on an erase block boundary if |
102 __PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors); |
102 // (1) the iEraseBlockSize is specified |
103 ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors)); |
103 // (2) the start of the partition is already aligned to an erase block boundary, |
104 ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors); |
104 // i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize |
105 if ((eraseblockSizeInSectors != 0) && |
105 __PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors); |
106 (iHiddenSectors % eraseblockSizeInSectors == 0) && |
106 TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2; |
107 (IsPowerOf2(eraseblockSizeInSectors)) && |
107 __PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors); |
108 (eraseblockSizeInSectors >= blockSizeInSectors)) |
108 ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors)); |
109 { |
109 ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors); |
110 TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors); |
110 if ((eraseblockSizeInSectors != 0) && |
111 ASSERT(r == KErrNone); |
111 (iHiddenSectors % eraseblockSizeInSectors == 0) && |
112 (void) r; |
112 (IsPowerOf2(eraseblockSizeInSectors)) && |
113 } |
113 (eraseblockSizeInSectors >= blockSizeInSectors)) |
114 __PRINT1(_L("iReservedSectors: %d"),iReservedSectors); |
114 { |
115 __PRINT1(_L("FirstDataSector: %d"), FirstDataSector()); |
115 TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors); |
|
116 ASSERT(r == KErrNone); |
|
117 (void) r; |
|
118 } |
|
119 __PRINT1(_L("iReservedSectors: %d"),iReservedSectors); |
|
120 __PRINT1(_L("FirstDataSector: %d"), FirstDataSector()); |
|
121 |
|
122 // If we've shrunk the number of clusters by so much that it's now invalid for this FAT type |
|
123 // then we need to decrease the cluster size and try again, otherwise we're finshed. |
|
124 if (SuggestFatType() == fatType) |
|
125 break; |
|
126 } |
|
127 __PRINT1(_L("iSectorsPerCluster (final): %d"),iSectorsPerCluster); |
116 |
128 |
117 return KErrNone; |
129 return KErrNone; |
118 } |
130 } |
119 |
131 |
120 TInt CFatFormatCB::FirstDataSector() const |
132 TInt CFatFormatCB::FirstDataSector() const |
122 TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector; |
134 TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector; |
123 return iHiddenSectors + iReservedSectors + iNumberOfFats*iSectorsPerFat + rootDirSectors; |
135 return iHiddenSectors + iReservedSectors + iNumberOfFats*iSectorsPerFat + rootDirSectors; |
124 } |
136 } |
125 |
137 |
126 void CFatFormatCB::AdjustClusterSize(TInt aRecommendedSectorsPerCluster) |
138 void CFatFormatCB::AdjustClusterSize(TInt aRecommendedSectorsPerCluster) |
127 { |
139 { |
128 const TInt KMaxSecPerCluster = 64; // 32K |
140 const TInt KMaxSecPerCluster = 64; // 32K |
129 while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2)) |
141 while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2)) |
130 iSectorsPerCluster<<= 1; |
142 iSectorsPerCluster<<= 1; |
131 } |
143 } |
132 |
144 |
133 // AdjustFirstDataSectorAlignment() |
145 // AdjustFirstDataSectorAlignment() |
134 // Attempts to align the first data sector on an erase block boundary by modifying the |
146 // Attempts to align the first data sector on an erase block boundary by modifying the |
135 // number of reserved sectors. |
147 // number of reserved sectors. |
136 TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TInt aEraseBlockSizeInSectors) |
148 TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TInt aEraseBlockSizeInSectors) |