Example #1
0
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    :  MFS_Read_device_sector
* Returned Value   :  error_code
* Comments  :
*     Reads one sector from the device
*END*---------------------------------------------------------------------*/
_mfs_error MFS_Read_device_sector
    (
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    uint_32                 sector_number,  /*[IN] sector number to read/write from/to file system medium */
    char_ptr                sector_ptr      /*[IN/OUT] address of where data is to be stored/written */
    )
{
    return MFS_Read_device_sectors(drive_ptr, sector_number, 1, MFSCFG_MAX_READ_RETRIES, sector_ptr, NULL);
}  
Example #2
0
uint32_t  MFS_Read
    (
    MFS_HANDLE_PTR          handle, /*[IN] file handle upon which the action is to be taken */
    MFS_DRIVE_STRUCT_PTR    drive_ptr,
    uint32_t                num_bytes,      /*[IN] number of bytes to be read */
    char                    *buffer_address, /*[IN/OUT] bytes are read into this buffer */
    _mfs_error_ptr          error_ptr       /*[IN/OUT] error code is written to this address */
    )
{
    uint32_t                 location;
    uint32_t                 bytes_read;
    uint32_t                 bytes_left_in_file;
    uint32_t                 copy_size;
    uint32_t                 cluster_offset;
    uint32_t                 sector_number, sector_index;
    uint32_t                 sector_offset;
    uint32_t                 whole_sectors;
    uint32_t                 cont_sectors;
    uint32_t                 proc_sectors;
    _mfs_error               error, temp_error;
    bool                     eof_reached;
    uint32_t                 file_size;

    if ( num_bytes == 0 )
    {
        MFS_set_error_and_return(error_ptr,MFS_NO_ERROR,0);
    }

    if ( buffer_address == NULL )
    {
        MFS_set_error_and_return(error_ptr,MFS_INVALID_PARAMETER,0);
    }

    error = MFS_lock_dos_disk(drive_ptr);
    if ( error != MFS_NO_ERROR )
    {
        MFS_set_error_and_return(error_ptr,error,0);
    }

    if ( handle->ACCESS != MFS_ACCESS_READ_ONLY &&
        handle->ACCESS != MFS_ACCESS_READ_WRITE )
    {
        MFS_unlock(drive_ptr,FALSE);
        MFS_set_error_and_return(error_ptr,MFS_ACCESS_DENIED,0);
    }


    if ( handle->CURRENT_CLUSTER == 0 )
    {
        handle->PREVIOUS_CLUSTER = 0;
        handle->CURRENT_CLUSTER = clustoh(handle->DIR_ENTRY.HFIRST_CLUSTER, handle->DIR_ENTRY.LFIRST_CLUSTER);
    }
    else if ( handle->CURRENT_CLUSTER == CLUSTER_EOF )
    {
        MFS_unlock(drive_ptr,FALSE);
        MFS_set_error_and_return(error_ptr,MFS_EOF,0);
    }


    bytes_read = 0;
    eof_reached = FALSE;
    location = handle->LOCATION;

    /*
    ** Can't read past file size
    */
    file_size = mqx_dtohl(handle->DIR_ENTRY.FILE_SIZE);
    if ( location > file_size )
    {
        location = file_size;
    }
    bytes_left_in_file = file_size - location;
    if ( num_bytes > bytes_left_in_file )
    {
        eof_reached = TRUE;
        num_bytes = bytes_left_in_file;
    }

    if ( bytes_left_in_file )
    {
        /*
        ** Read the number of bytes from the current file
        ** position to the end of the current cluster
        */
        cluster_offset = OFFSET_WITHIN_CLUSTER(location);
        sector_index = CLUSTER_OFFSET_TO_SECTOR(cluster_offset);
        sector_number = CLUSTER_TO_SECTOR(handle->CURRENT_CLUSTER) + sector_index;
        sector_offset = OFFSET_WITHIN_SECTOR(location);

        /* Read partial sector if sector_offet is non-zero */
        if (sector_offset != 0)
        {
            error = MFS_Read_data_sector(drive_ptr, handle, sector_number, TRUE);
            if ( error == MFS_NO_ERROR )
            {
                /* The requested lenght of data may span the sector to it's end  */
                copy_size = min(num_bytes, drive_ptr->BPB.SECTOR_SIZE-sector_offset);

                _mem_copy(&drive_ptr->DATA_SECTOR_PTR[sector_offset], buffer_address, copy_size);
                bytes_read=copy_size;

                /*
                ** Check to see if we need to advance to the next sector, which has
                ** the side effect of increasing the cluster number if required.
                */
                if ( (sector_offset+bytes_read) >= drive_ptr->BPB.SECTOR_SIZE )
                {
                    temp_error = MFS_next_data_sector(drive_ptr, handle, &sector_index, &sector_number);
                    /* Only an error if we are not done reading */
                    if ( bytes_read<num_bytes )
                    {
                        error = temp_error;
                    }
                }
            }
        }

        /* Check whether the application buffer is properly aligned */
        if ((((uint32_t)buffer_address+bytes_read) & drive_ptr->ALIGNMENT_MASK) == 0)
        {
            /* Yes, use zero copy approach */
            whole_sectors = (num_bytes - bytes_read) >> drive_ptr->SECTOR_POWER;
            while ((whole_sectors > 0) && (error == MFS_NO_ERROR))
            {
                cont_sectors = drive_ptr->BPB.SECTORS_PER_CLUSTER - sector_index;
                if (cont_sectors > whole_sectors)
                    cont_sectors = whole_sectors;

                error = MFS_Read_device_sectors(drive_ptr, sector_number, cont_sectors, MFSCFG_MAX_READ_RETRIES, buffer_address+bytes_read, &proc_sectors);

                if (proc_sectors > 0)
                {
                    bytes_read += proc_sectors * drive_ptr->BPB.SECTOR_SIZE;
                    whole_sectors -= proc_sectors;

                    /* Advance to next unprocessed sector */
                    sector_index += proc_sectors - 1;
                    temp_error = MFS_next_data_sector(drive_ptr, handle, &sector_index, &sector_number);
                    /* Only an error if we are not done reading */
                    if ((error==MFS_NO_ERROR) && (bytes_read<num_bytes))
                    {
                        error = temp_error;
                    }
                }
            }
        }
        else
        {