in ff_ioman.c [1364:1607]
FF_Error_t FF_Mount( FF_Disk_t * pxDisk,
BaseType_t xPartitionNumber )
{
FF_Partition_t * pxPartition;
FF_Buffer_t * pxBuffer = 0;
FF_Error_t xError = FF_ERR_NONE;
int16_t rootEntryCount;
FF_IOManager_t * pxIOManager = pxDisk->pxIOManager;
/* HT TODO: find a method to safely determine the FAT type: 32/16/12 */
/* other than only counting Clusters */
/* UBaseType_t fat32Indicator = 0; */
FF_Part_t * pxMyPartition;
#if ( ffconfigHASH_CACHE != 0 )
BaseType_t i;
#endif
FF_Error_t xPartitionCount = 0;
FF_SPartFound_t partsFound;
partsFound.iCount = 0;
do
{
if( pxIOManager == NULL )
{
xError = FF_ERR_NULL_POINTER | FF_MOUNT;
break;
}
pxPartition = &( pxIOManager->xPartition );
#if ( ffconfigREMOVABLE_MEDIA != 0 )
{
pxIOManager->ucFlags &= ( uint8_t ) ( ~( FF_IOMAN_DEVICE_IS_EXTRACTED ) );
}
#endif /* ffconfigREMOVABLE_MEDIA */
/* FF_IOMAN_InitBufferDescriptors will clear 'pxBuffers' */
memset( pxIOManager->pucCacheMem, '\0', ( size_t ) pxIOManager->usSectorSize * pxIOManager->usCacheSize );
#if ( ffconfigHASH_CACHE != 0 )
{
memset( pxIOManager->xHashCache, '\0', sizeof( pxIOManager->xHashCache ) );
for( i = 0; i < ffconfigHASH_CACHE_DEPTH; i++ )
{
/* _HT_ Check why did JW put it to 100? */
pxIOManager->xHashCache[ i ].ulMisses = 100;
}
}
#endif
#if ( ffconfigPATH_CACHE != 0 )
{
memset( pxPartition->pxPathCache, '\0', sizeof( pxPartition->pxPathCache ) );
}
#endif
FF_IOMAN_InitBufferDescriptors( pxIOManager );
pxIOManager->FirstFile = 0;
xPartitionCount = FF_PartitionSearch( pxIOManager, &partsFound );
if( FF_isERR( xPartitionCount ) )
{
xError = xPartitionCount;
break;
}
if( xPartitionCount == 0 )
{
xError = FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION | FF_MOUNT;
break;
}
if( xPartitionNumber >= xPartitionCount )
{
xError = FF_ERR_IOMAN_INVALID_PARTITION_NUM | FF_MOUNT;
break;
}
pxMyPartition = &( partsFound.pxPartitions[ xPartitionNumber ] );
pxPartition->ulBeginLBA = pxMyPartition->ulStartLBA;
if( pxMyPartition->ucPartitionID == 0xEE )
{
xError = FF_GetEfiPartitionEntry( pxIOManager, xPartitionNumber );
if( FF_isERR( xError ) )
{
break;
}
}
/* Now we get the Partition sector. */
pxBuffer = FF_GetBuffer( pxIOManager, pxPartition->ulBeginLBA, FF_MODE_READ );
if( pxBuffer == NULL )
{
xError = FF_ERR_DEVICE_DRIVER_FAILED | FF_MOUNT;
break;
}
pxPartition->usBlkSize = FF_getShort( pxBuffer->pucBuffer, FF_FAT_BYTES_PER_SECTOR );
if( ( ( pxPartition->usBlkSize % 512 ) != 0 ) || ( pxPartition->usBlkSize == 0 ) )
{
/* An error here should override the current error, as its likely fatal. */
xError = FF_ReleaseBuffer( pxIOManager, pxBuffer );
if( FF_isERR( xError ) == pdFALSE )
{
xError = FF_ERR_IOMAN_INVALID_FORMAT | FF_MOUNT;
}
break;
}
/* Assume FAT16, then we'll adjust if its FAT32 */
pxPartition->usReservedSectors = FF_getShort( pxBuffer->pucBuffer, FF_FAT_RESERVED_SECTORS );
pxPartition->ulFATBeginLBA = pxPartition->ulBeginLBA + pxPartition->usReservedSectors;
pxPartition->ucNumFATS = ( uint8_t ) FF_getShort( pxBuffer->pucBuffer, FF_FAT_NUMBER_OF_FATS );
pxPartition->ulSectorsPerFAT = ( uint32_t ) FF_getShort( pxBuffer->pucBuffer, FF_FAT_16_SECTORS_PER_FAT );
pxPartition->ulSectorsPerCluster = FF_getChar( pxBuffer->pucBuffer, FF_FAT_SECTORS_PER_CLUS );
/* Set the BlockFactor (How many real-blocks in a fake block!). */
pxPartition->ucBlkFactor = ( uint8_t ) ( pxPartition->usBlkSize / pxIOManager->usSectorSize );
pxPartition->ulTotalSectors = ( uint32_t ) FF_getShort( pxBuffer->pucBuffer, FF_FAT_16_TOTAL_SECTORS );
if( pxPartition->ulTotalSectors == 0 )
{
pxPartition->ulTotalSectors = FF_getLong( pxBuffer->pucBuffer, FF_FAT_32_TOTAL_SECTORS );
}
if( pxPartition->ulSectorsPerFAT == 0 )
{ /* FAT32 */
pxPartition->ulSectorsPerFAT = FF_getLong( pxBuffer->pucBuffer, FF_FAT_32_SECTORS_PER_FAT );
pxPartition->ulRootDirCluster = FF_getLong( pxBuffer->pucBuffer, FF_FAT_ROOT_DIR_CLUSTER );
memcpy( pxPartition->pcVolumeLabel, pxBuffer->pucBuffer + FF_FAT_32_VOL_LABEL, sizeof( pxPartition->pcVolumeLabel ) - 1 );
}
else
{ /* FAT16 */
pxPartition->ulRootDirCluster = 1; /* 1st Cluster is RootDir! */
memcpy( pxPartition->pcVolumeLabel, pxBuffer->pucBuffer + FF_FAT_16_VOL_LABEL, sizeof( pxPartition->pcVolumeLabel ) - 1 );
}
pxPartition->ulClusterBeginLBA = pxPartition->ulFATBeginLBA + ( pxPartition->ucNumFATS * pxPartition->ulSectorsPerFAT );
#if ( ffconfigWRITE_FREE_COUNT != 0 )
{
pxPartition->ulFSInfoLBA = pxPartition->ulBeginLBA + FF_getShort( pxBuffer->pucBuffer, 48 );
}
#endif
FF_ReleaseBuffer( pxIOManager, pxBuffer ); /* Release the buffer finally! */
if( pxPartition->usBlkSize == 0 )
{
xError = FF_ERR_IOMAN_INVALID_FORMAT | FF_MOUNT;
break;
}
rootEntryCount = FF_getShort( pxBuffer->pucBuffer, FF_FAT_ROOT_ENTRY_COUNT );
pxPartition->ulRootDirSectors = ( ( rootEntryCount * 32 ) + pxPartition->usBlkSize - 1 ) / pxPartition->usBlkSize;
pxPartition->ulFirstDataSector = pxPartition->ulClusterBeginLBA + pxPartition->ulRootDirSectors;
pxPartition->ulDataSectors = pxPartition->ulTotalSectors - ( pxPartition->usReservedSectors + ( pxPartition->ucNumFATS * pxPartition->ulSectorsPerFAT ) + pxPartition->ulRootDirSectors );
/*
* HT: fat32Indicator not yet used
* As there is so much confusion about the FAT types
* I was thinking of collecting indications for either FAT12, 16 or 32
*/
/*
* if( FF_getShort( pxBuffer->pucBuffer, FF_FAT_EXT_BOOT_SIGNATURE ) == 0x29 )
* fat32Indicator++;
* if( rootEntryCount == 0 )
* fat32Indicator++;
*/
if( pxPartition->ulSectorsPerCluster == 0 )
{
xError = FF_ERR_IOMAN_INVALID_FORMAT | FF_MOUNT;
break;
}
pxPartition->ulNumClusters = pxPartition->ulDataSectors / pxPartition->ulSectorsPerCluster;
xError = prvDetermineFatType( pxIOManager );
if( FF_isERR( xError ) )
{
break;
}
if( !rootEntryCount && ( pxPartition->ucType != FF_T_FAT32 ) )
{
FF_PRINTF( "No root dir, must be a FAT32\n" );
pxPartition->ucType = FF_T_FAT32;
}
pxPartition->ucPartitionMounted = pdTRUE;
pxPartition->ulLastFreeCluster = 0;
#if ( ffconfigMOUNT_FIND_FREE != 0 )
{
FF_LockFAT( pxIOManager );
{
/* The parameter 'pdFALSE' means: do not claim the free cluster found. */
pxPartition->ulLastFreeCluster = FF_FindFreeCluster( pxIOManager, &xError, pdFALSE );
}
FF_UnlockFAT( pxIOManager );
if( FF_isERR( xError ) )
{
if( FF_GETERROR( xError ) == FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE )
{
pxPartition->ulLastFreeCluster = 0;
}
else
{
break;
}
}
pxPartition->ulFreeClusterCount = FF_CountFreeClusters( pxIOManager, &xError );
if( FF_isERR( xError ) )
{
break;
}
}
#else /* if ( ffconfigMOUNT_FIND_FREE != 0 ) */
{
pxPartition->ulFreeClusterCount = 0;
}
#endif /* ffconfigMOUNT_FIND_FREE */
}
while( pdFALSE );
if( FF_isERR( xError ) == pdFALSE )
{
xError = 0;
}
return xError;
} /* FF_Mount() */