Fx_mo.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:26k
- /**************************************************************************/
- /* */
- /* Copyright (c) 1996-2002 by Express Logic Inc. */
- /* */
- /* This software is copyrighted by and is the sole property of Express */
- /* Logic, Inc. All rights, title, ownership, or other interests */
- /* in the software remain the property of Express Logic, Inc. This */
- /* software may only be used in accordance with the corresponding */
- /* license agreement. Any unauthorized use, duplication, transmission, */
- /* distribution, or disclosure of this software is expressly forbidden. */
- /* */
- /* This Copyright notice may not be removed or modified without prior */
- /* written consent of Express Logic, Inc. */
- /* */
- /* Express Logic, Inc. reserves the right to modify this software */
- /* without notice. */
- /* */
- /* Express Logic, Inc. info@expresslogic.com */
- /* 11423 West Bernardo Court http://www.expresslogic.com */
- /* San Diego, CA 92127 */
- /* */
- /**************************************************************************/
- /**************************************************************************/
- /**************************************************************************/
- /** */
- /** FileX Component */
- /** */
- /** Media (MED) */
- /** */
- /**************************************************************************/
- /**************************************************************************/
- #include "Config.h" // Global Configuration - do not remove!
- #ifdef ENABLE_FILEX
- #ifdef _DEBUG
- #undef IFTRACE
- #define IFTRACE if (gTraceFileSys)
- #include "DebugDbgMain.h"
- #endif //_DEBUG
- #define FX_SOURCE_CODE
- /* Include necessary system files. */
- #include "PlaycoreFileSysFileXfx_api.h"
- #include "PlaycoreFileSysFileXfx_sys.h"
- #include "PlaycoreFileSysFileXfx_med.h"
- #include "PlaycoreFileSysFileXfx_uti.h"
- /**************************************************************************/
- /* */
- /* FUNCTION RELEASE */
- /* */
- /* _fx_media_open PORTABLE C */
- /* 3.0 */
- /* AUTHOR */
- /* */
- /* William E. Lamie, Express Logic, Inc. */
- /* */
- /* DESCRIPTION */
- /* */
- /* This function opens the specified media with the supplied device */
- /* driver. The specified media must conform to the MS-DOS compatible */
- /* file format, which is verified during the media open process. In */
- /* addition, the supplied FileX device driver must also conform to */
- /* the FileX device driver specification. */
- /* */
- /* The MS-DOS boot sector (512 bytes) that is verified by this */
- /* function must look like the following: */
- /* */
- /* Byte Offset Meaning Size */
- /* */
- /* 0x000 Jump Instructions 3 */
- /* 0x003 OEM Name 8 */
- /* 0x00B *Bytes per Sector 2 */
- /* 0x00D *Sectors per Cluster 1 */
- /* 0x00E *Reserved Sectors 2 */
- /* 0x010 *Number of FATs 1 */
- /* 0x011 *Max Root Dir Entries 2 */
- /* 0x013 *Number of Sectors 2 */
- /* 0x015 Media Type 1 */
- /* 0x016 *Sectors per FAT 2 */
- /* 0x018 *Sectors per Track 2 */
- /* 0x01A *Number of Heads 2 */
- /* 0x01C *Hidden Sectors 4 */
- /* 0x020 *Huge Sectors 4 */
- /* 0x024 Drive Number 1 */
- /* 0x025 Reserved 1 */
- /* 0x026 Boot Signature 1 */
- /* 0x027 Volume ID 4 */
- /* 0x02B Volume Label 11 */
- /* 0x036 File System Type 8 */
- /* ... ... ... */
- /* 0x1FE **Signature (0x55aa) 2 */
- /* */
- /* * Denotes which elements of the boot record */
- /* FileX uses. */
- /* */
- /* **Denotes the element is checked by the I/O */
- /* driver. This eliminates the need for a minimum */
- /* 512-byte buffer for FileX. */
- /* */
- /* Note: All values above are in little endian format, i.e. the LSB is */
- /* in the lowest address. */
- /* */
- /* INPUT */
- /* */
- /* media_ptr Media control block pointer */
- /* media_name Pointer to media name string */
- /* media_driver Media driver entry function */
- /* driver_info_ptr Optional information pointer */
- /* supplied to media driver */
- /* memory_ptr Pointer to memory used by the */
- /* FileX for this media. */
- /* memory_size Size of media memory - must */
- /* at least 512 bytes and */
- /* one sector size. */
- /* */
- /* OUTPUT */
- /* */
- /* return status */
- /* */
- /* CALLS */
- /* */
- /* I/O Driver */
- /* _fx_media_boot_info_extract Extract media information */
- /* _fx_utility_FAT_entry_read Pickup FAT entry contents */
- /* tx_semaphore_create Create protection semaphore */
- /* */
- /* CALLED BY */
- /* */
- /* Application Code */
- /* */
- /* RELEASE HISTORY */
- /* */
- /* DATE NAME DESCRIPTION */
- /* */
- /* 01-01-1999 William E. Lamie Initial Version 1.0 */
- /* 04-19-1999 William E. Lamie Corrected logic for 12/16-bit */
- /* FAT determination, */
- /* resulting in version 1.0a */
- /* 03-01-2000 William E. Lamie Modified comment(s), moved */
- /* data sector start setup to */
- /* ensure it is valid prior to */
- /* calculating total clusters, */
- /* and added initialization */
- /* current path string, */
- /* resulting in version 1.0b. */
- /* 01-28-2001 William E. Lamie Modified comment(s), */
- /* added support for logical */
- /* sector cache, optimized FAT */
- /* entry search, and local */
- /* path setup, resulting in */
- /* version 2.0. */
- /* 03-01-2002 Mohammad N. Minhaz Modified comment(s), and */
- /* added logic to read FAT32 */
- /* boot record, resulting in */
- /* version 3.0. */
- /* */
- /**************************************************************************/
- UINT _fx_media_open(FX_MEDIA *media_ptr, CHAR *media_name,
- VOID (*media_driver)(FX_MEDIA *), VOID *driver_info_ptr,
- VOID *memory_ptr, ULONG memory_size, UINT partition)
- {
- FX_MEDIA_PTR tail_ptr;
- ULONG cluster_number;
- ULONG FAT_entry;
- ULONG i;
- FX_CACHED_SECTOR *cache_entry_ptr;
- UINT status;
- /* Save the basic information in the media control block. */
- media_ptr -> fx_media_name = media_name;
- media_ptr -> fx_media_driver_entry = media_driver;
- media_ptr -> fx_media_memory_buffer = (UCHAR_PTR)memory_ptr;
- media_ptr -> fx_media_sector_cache_end = (UCHAR_PTR)memory_ptr;
- media_ptr -> fx_media_memory_buffer_orig = (UCHAR_PTR)memory_ptr;
- media_ptr -> fx_media_memory_size = memory_size;
- /* Initialize the supplied media I/O driver. First, build the
- initialize driver request. */
- media_ptr -> fx_media_driver_request = FX_DRIVER_INIT;
- media_ptr -> fx_media_driver_status = FX_IO_ERROR;
- media_ptr -> fx_media_driver_buffer = memory_ptr;
- media_ptr -> fx_media_driver_info = driver_info_ptr;
- media_ptr -> fx_media_driver_write_protect = FX_FALSE;
- media_ptr -> fx_media_driver_free_sector_update = FX_FALSE;
- /* Call the specified I/O driver with the initialize request. */
- (media_ptr -> fx_media_driver_entry) (media_ptr);
- /* Determine if the I/O driver initialized successfully. */
- if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
- {
- /* Return the driver error status. */
- return(FX_IO_ERROR);
- }
- // Get geometry of device.
- status = _fx_utility_get_geometry( media_ptr, FALSE, 0, 0 );
-
- if ( status != FX_SUCCESS )
- {
- return status;
- }
- /* Read the boot sector from the device. Build the read boot sector
- command. fx_media_driver_logical_sector holds the partition to be
- opened. */
- media_ptr -> fx_media_driver_request = FX_DRIVER_BOOT_READ;
- media_ptr -> fx_media_driver_status = FX_IO_ERROR;
- media_ptr -> fx_media_driver_buffer = memory_ptr;
- media_ptr -> fx_media_driver_logical_sector = partition;
- media_ptr -> fx_media_driver_sectors = 1;
- /* Invoke the driver to read the boot sector. */
- (media_ptr -> fx_media_driver_entry) (media_ptr);
- /* Determine if the boot sector was read correctly. */
- if (media_ptr -> fx_media_driver_status != FX_SUCCESS)
- {
- /* Create the media protection structure if FX_SINGLE_THREAD is not
- defined. */
- #ifndef FX_SINGLE_THREAD
- os_semaphore_create(&(media_ptr -> fx_media_protect), "FileX Media Semaphore", 1);
- #endif
- /* Load the media ID field in the media control block. */
- media_ptr -> fx_media_id = (ULONG) FX_MEDIA_DIRECT_ID;
- /* There are no hidden sectors in the media. */
- media_ptr -> fx_media_hidden_sectors = 0;
- /* Default value. */
- media_ptr ->fx_media_bytes_per_sector = 512;
- /* Return a successful status. */
- return(FX_DIRECT_SUCCESS);
- }
- /* Extract and validate the media parameters from the boot sector. */
- if (_fx_media_boot_info_extract(media_ptr,
- media_ptr -> fx_media_driver_buffer) !=
- FX_SUCCESS)
- {
- /* Return the invalid media error status. */
- return(FX_MEDIA_INVALID);
- }
- /* Determine how many logical sector's can be cached with user's supplied
- buffer area - there must be at least enough for one sector! */
- media_ptr -> fx_media_sector_cache_size = memory_size / media_ptr -> fx_media_bytes_per_sector;
- /* Is there at least one? */
- if (media_ptr -> fx_media_sector_cache_size == 0)
- {
- /* Error in the buffer size supplied by user. */
- return(FX_BUFFER_ERROR);
- }
- /* Adjust the internal cache to fit the fixed number of sector cache control blocks
- built into the media control block. */
- if (media_ptr -> fx_media_sector_cache_size > FX_MAX_SECTOR_CACHE)
- {
- /* Adjust the number of cache sectors downward. If this is insufficient,
- the FX_MAX_SECTOR_CACHE constant in FX_API.H must be changed and the FileX
- library must be rebuilt. */
- media_ptr -> fx_media_sector_cache_size = FX_MAX_SECTOR_CACHE;
- }
- /* Otherwise, everything is okay. Initialize the data structures for managing the
- logical sector cache. */
- i = (UINT) media_ptr -> fx_media_sector_cache_size;
- cache_entry_ptr = media_ptr -> fx_media_sector_cache;
- while (i--)
- {
- /* Initialize each of the cache entries. */
- cache_entry_ptr -> fx_cached_sector_memory_buffer = (UCHAR_PTR) memory_ptr;
- cache_entry_ptr -> fx_cached_sector = 0;
- cache_entry_ptr -> fx_cached_sector_buffer_dirty = FX_FALSE;
- cache_entry_ptr -> fx_cached_sector_next_used = cache_entry_ptr + 1;
- /* Move to the next cache sector entry. */
- cache_entry_ptr++;
- /* Update the memory pointer to the next buffer slot. */
- memory_ptr = (VOID *) (((UCHAR_PTR) memory_ptr) + media_ptr -> fx_media_bytes_per_sector);
- }
- /* Backup to the last cache entry to set it's next pointer to NULL. */
- cache_entry_ptr--;
- cache_entry_ptr -> fx_cached_sector_next_used = FX_NULL;
- /* Remember the last memory address used by the caching logic. */
- media_ptr -> fx_media_sector_cache_end = (UCHAR_PTR) memory_ptr;
- /* Setup the head pointer of the list. */
- media_ptr -> fx_media_sector_cache_list_ptr = media_ptr -> fx_media_sector_cache;
- if (media_ptr -> fx_media_32_bit_FAT == FX_TRUE)
- {
- /* fx_media_root_sector_start has been extracted from FX_ROOT_CLUS_32 in fx_mbie.c */
- media_ptr -> fx_media_root_sector_start = media_ptr -> fx_media_data_sector_start +
- (media_ptr -> fx_media_root_clus_32 - FX_FAT_ENTRY_START) *
- media_ptr -> fx_media_sectors_per_cluster;
- /* Calculate maximum possible value for fx_media_root_directory_entries */
- i = 0;
- for(cluster_number = media_ptr->fx_media_root_clus_32;;)
- {
- status = _fx_utility_FAT_entry_read(media_ptr, cluster_number, &FAT_entry);
- i++;
- /* Determine if the read was successful. */
- if (status != FX_SUCCESS)
- return(FX_FAT_READ_ERROR);
- if ((cluster_number == FAT_entry) || (i > media_ptr -> fx_media_total_sectors))
- return(FX_FAT_READ_ERROR);
- if (FAT_entry >= FX_RESERVED_1_32)
- break;
- cluster_number = FAT_entry;
- }
- media_ptr -> fx_media_root_directory_entries = (i * media_ptr->fx_media_sectors_per_cluster *
- media_ptr->fx_media_bytes_per_sector) / FX_DIR_ENTRY_SIZE;
- }
- /* Calculate the number of available clusters. */
- media_ptr -> fx_media_available_clusters = 0;
- /* Set the cluster search start to an invalid value. */
- media_ptr -> fx_media_cluster_search_start = 0;
- /* Loop to read each cluster entry in the first FAT. */
- for (cluster_number = FX_FAT_ENTRY_START;
- cluster_number < (media_ptr -> fx_media_total_clusters) + FX_FAT_ENTRY_START;
- cluster_number++)
- {
- /* Read a FAT entry. */
- status = _fx_utility_FAT_entry_read(media_ptr, cluster_number, &FAT_entry);
- /* Determine if the read was successful. */
- if (status != FX_SUCCESS)
- return(FX_FAT_READ_ERROR);
- /* Now determine if the FAT entry is available. */
- if (FAT_entry == FX_FREE_CLUSTER)
- {
- /* Increment the number of available clusters. */
- media_ptr -> fx_media_available_clusters++;
- /* Check to see if the cluster search value is invalid. */
- if (media_ptr -> fx_media_cluster_search_start == 0)
- {
-
- /* Remember the first free cluster to start further searches from. */
- media_ptr -> fx_media_cluster_search_start = cluster_number;
- }
- }
- }
- /* If there were no free clusters, just set the search pointer to the
- first cluster number. */
- if (media_ptr -> fx_media_cluster_search_start == 0)
- media_ptr -> fx_media_cluster_search_start = FX_FAT_ENTRY_START;
- /* Setup the current working directory fields to default to the root
- directory. */
- media_ptr -> fx_media_default_path.fx_path_directory.fx_dir_entry_name[0] = 0;
- media_ptr -> fx_media_default_path.fx_path_string[0] = (CHAR) 0;
- media_ptr -> fx_media_default_path.fx_path_string[FX_MAXIMUM_PATH-1] = (CHAR) 0;
- media_ptr -> fx_media_default_path.fx_path_string[FX_MAXIMUM_PATH-2] = (CHAR) 0;
- media_ptr -> fx_media_default_path.fx_path_current_entry = 0;
- /* Initialize the opened file linked list and associated counter. */
- media_ptr -> fx_media_opened_file_list = FX_NULL;
- media_ptr -> fx_media_opened_file_count = 0;
- /* Create the media protection structure if FX_SINGLE_THREAD is not
- defined. */
- #ifndef FX_SINGLE_THREAD
- os_semaphore_create(&(media_ptr -> fx_media_protect), "FileX Media Semaphore", 1);
- #endif
- /* At this point, the media has been opened successfully. Place the
- media on the linked list of currently opened media. */
- /* Load the media ID field in the media control block. */
- media_ptr -> fx_media_id = (ULONG) FX_MEDIA_ID;
- /* Place the thread on the list of opened media. First,
- check for an empty list. */
- if (_fx_system_media_opened_ptr)
- {
- /* Pickup tail pointer. */
- tail_ptr = _fx_system_media_opened_ptr -> fx_media_opened_previous;
- /* Place the new media in the list. */
- _fx_system_media_opened_ptr -> fx_media_opened_previous = media_ptr;
- tail_ptr -> fx_media_opened_next = media_ptr;
- /* Setup this media's opened links. */
- media_ptr -> fx_media_opened_previous = tail_ptr;
- media_ptr -> fx_media_opened_next = _fx_system_media_opened_ptr;
- }
- else
- {
- /* The opened media list is empty. Add the media to empty list. */
- _fx_system_media_opened_ptr = media_ptr;
- media_ptr -> fx_media_opened_next = media_ptr;
- media_ptr -> fx_media_opened_previous = media_ptr;
- }
- /* Increment the opened media counter. */
- _fx_system_media_opened_count++;
- /* Return a successful status. */
- return(FX_SUCCESS);
- }
- /**************************************************************************/
- /* */
- /* FUNCTION RELEASE */
- /* */
- /* _fx_media_invalidate PORTABLE C */
- /* 3.0 */
- /* AUTHOR */
- /* */
- /* Ofir Alon, Zoran MicroElectronics Ltd. */
- /* */
- /* DESCRIPTION */
- /* */
- /* This function marks the specified media as closed, without touching */
- /* anything else or making flush operations. If any memory needs to be */
- /* freed, it will do so. This is used when we need to reopen a media */
- /* but it is possible that the media has changed (like a card taken */
- /* out and then another card inserted instead) so it will not be */
- /* to correct to flush the media. */
- /* */
- /* INPUT */
- /* */
- /* media_ptr Media control block pointer */
- /* */
- /* OUTPUT */
- /* */
- /* Return status */
- /* */
- /* CALLS */
- /* */
- /* None. */
- /* */
- /* CALLED BY */
- /* */
- /* Application Code */
- /* */
- /* RELEASE HISTORY */
- /* */
- /* DATE NAME DESCRIPTION */
- /* */
- /* 10-04-2002 Ofir Alon Initial Version 3.0 */
- /* */
- /**************************************************************************/
- UINT _fx_media_invalidate( FX_MEDIA *media_ptr )
- {
- // Mark media as closed.
- media_ptr->fx_media_id = FX_MEDIA_CLOSED_ID;
- #ifndef FX_SINGLE_THREAD
- tx_semaphore_delete(&(media_ptr -> fx_media_protect));
- #endif
- return FX_SUCCESS;
- }
- #endif