⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fal.cpp

📁 基于WINCE的文件系统FAL驱动
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

	2007 Modified by Chris Gray at Raza Microelectronics Inc for WinCE 5.0 optimizations
			(cgray@razamicro.com)

Module Name:    FAL.CPP

Abstract:       FLASH Abstraction Layer (FAL) for Windows CE

-----------------------------------------------------------------------------*/
#include <windows.h>
#include <windev.h>
#include "storemgr.h"

#include "fal.h"

Fal::Fal (DWORD dwStartLogSector, DWORD dwStartPhysSector, BOOL fReadOnly) :
    m_dwStartLogSector(dwStartLogSector),
    m_dwStartPhysSector(dwStartPhysSector),
    m_dwNumLogSectors(0),
    m_fReadOnly(fReadOnly)
{
    m_pMap = new MappingTable(dwStartLogSector, dwStartPhysSector);
    m_pSectorMgr = new SectorMgr();
}

Fal::~Fal()
{
    delete m_pMap;
    delete m_pSectorMgr;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FormatMedia()

Description:    Formats the FLASH by erasing all of the physical blocks
                on the media.

Notes:          The logical --> physical mapper and sector manager
                are automatically re-initialized.

Returns:        Boolean indicating success.
-------------------------------------------------------------------*/
BOOL Fal::FormatRegion(VOID)
{
    DWORD i = 0;

    if (m_fReadOnly)
    {
        SetLastError(ERROR_WRITE_PROTECT);
        return FALSE;
    }

    //----- 3. Erase all of the valid blocks on the FLASH media -----
    //         NOTE: The file system is responsible for then
    //               "logically" initializing the media as needed
    for(i = m_pRegion->dwStartPhysBlock; i < m_pRegion->dwStartPhysBlock + m_pRegion->dwNumPhysBlocks; i++)
    {
        if(FMD.pGetBlockStatus((BLOCK_ID)i) & (BLOCK_STATUS_BAD | BLOCK_STATUS_RESERVED))
        {
            // Don't erase bad blocks on the media or blocks reserved for other use (such as bootloader).
            continue;
        }

        if(!FMD.pEraseBlock((BLOCK_ID)i))
        {
            ReportError((TEXT("FLASHDRV.DLL:FormatMedia() - FMD_EraseBlock(%d) failed\r\n"), i));

            if(!FMD.pSetBlockStatus((BLOCK_ID)i, BLOCK_STATUS_BAD))
            {
                ReportError((TEXT("FLASHDRV.FormatMedia() - FMD_MarkBlockBad(%d) failed\r\n"), i));
            }
        }
    }
    return TRUE;
}



/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       InternalReadFromMedia()

Description:    Performs the specified scatter/gather READ request from the media.

Notes:          After parsing the parameters, the actual READ request is handled
                by the FLASH Media Driver (FMD).

Returns:        Boolean indicating success.
-------------------------------------------------------------------------------*/
BOOL Fal::ReadFromMedia(PSG_REQ pSG_req, BOOL fDoMap)
{
    static PSG_BUF      pSGbuff             = NULL;
    static PUCHAR       pBuff               = NULL;

    static DWORD        dwSGBuffNum          = 0;
    static DWORD        dwSGBuffPos          = 0;
    static DWORD        dwSectorAddr        = 0;

    static SECTOR_ADDR  physicalSectorAddr  = 0;

    CELOG_ReadSectors(pSG_req->sr_start, pSG_req->sr_num_sec);

    //----- 1. Parse the scatter/gather request to determine if it can be fulfilled -----
    pSG_req->sr_status = ERROR_IO_PENDING;

    //----- 2. Now service the sector READ request(s) -----
    //         NOTE: The FLASH Media Driver (FMD) is invoked to read the data off the media
    for(dwSGBuffNum=0; dwSGBuffNum<pSG_req->sr_num_sg; dwSGBuffNum++)
    {
        dwSGBuffPos  = 0;

        // Get a pointer to the scatter/gather buffer
        pSGbuff = &(pSG_req->sr_sglist[dwSGBuffNum]);

/* ctg
        if (fDoMap)
        {
            // Open the sg buffer; performs caller access check.
            if (FAILED (CeOpenCallerBuffer (
                    (PVOID*)&pBuff,
                    pSGbuff->sb_buf,
                    pSGbuff->sb_len,
                    ARG_O_PTR,
                    FALSE )))
            {
                ReportError((TEXT("FLASHDRV.DLL:ReadFromMedia() - CeOpenCallerBuffer() failed, couldn't obtain pointer to buffer.\r\n"), 0));
                pSG_req->sr_status = ERROR_INSUFFICIENT_BUFFER;         // Assume CeOpenCallerBuffer() failed because buffer was invalid
                goto READ_ERROR;
            }
// need??			pBuff = (PUCHAR)MapCallerPtr(pSGbuff->sb_buf,pSGbuff->sb_len);
        }
        else
*/
        {
            pBuff = pSGbuff->sb_buf;
        }

        for(dwSectorAddr=pSG_req->sr_start;
            dwSectorAddr<(pSG_req->sr_start + pSG_req->sr_num_sec) && ((pSGbuff->sb_len - dwSGBuffPos) >= g_pFlashMediaInfo->dwDataBytesPerSector);
            dwSectorAddr++)
        {
            //----- 3. Perform the LOGICAL -> PHYSICAL mapping to determine the physical sector address. -----
            if((!m_pMap->GetPhysicalSectorAddr((SECTOR_ADDR)dwSectorAddr, &physicalSectorAddr)) || (physicalSectorAddr == UNMAPPED_LOGICAL_SECTOR))
            {
                DEBUGMSG(ZONE_READ_OPS, (TEXT("FLASHDRV.DLL:ReadFromMedia() - Unable to determine physical sector address for logical sector 0x%08x\r\n"), dwSectorAddr));

/*
                if (fDoMap)
                {
                    // Close the sg buffer.
                    VERIFY (SUCCEEDED (CeCloseCallerBuffer (
                        pBuff,
                        pSGbuff->sb_buf,
                        pSGbuff->sb_len,
                        ARG_O_PTR )));
                }
*/

                // RARE CONDITION: The file system has just asked us to read a sector that it has NEVER written
                //                 to;  in this situation, we don't read any data from the media and can just
                //                 return SUCCESS.
                pSG_req->sr_status = ERROR_SUCCESS;
                return TRUE;
            }

            //----- For debugging purposes, print out the logical --> physical sector mapping... -----
            DEBUGMSG(ZONE_READ_OPS, (TEXT("FLASHDRV.DLL:ReadFromMedia() - logicalSector 0x%08x --> physicalSector 0x%08x\r\n"), dwSectorAddr, physicalSectorAddr));

            //----- 4. Invoke the FLASH Media Driver (FMD) to read the sector data from the media -----
            //         NOTE: Currently, only one sector is read at a time (last parameter)
            if(!FMD.pReadSector(physicalSectorAddr, (pBuff+dwSGBuffPos), NULL, 1))
            {
                ReportError((TEXT("FLASHDRV.DLL:FMD_ReadSector() failed!\r\n")));

                if (fDoMap)
                {
/* ctg
                    // Close the sg buffer.
                    VERIFY (SUCCEEDED (CeCloseCallerBuffer (
                        pBuff,
                        pSGbuff->sb_buf,
                        pSGbuff->sb_len,
                        ARG_O_PTR )));
*/
                }

                pSG_req->sr_status = ERROR_READ_FAULT;
                goto READ_ERROR;
            }
            dwSGBuffPos  += g_pFlashMediaInfo->dwDataBytesPerSector;
        }

        if (fDoMap)
        {
/* ctg
            // Close the sg buffer.
            VERIFY (SUCCEEDED (CeCloseCallerBuffer (
                pBuff,
                pSGbuff->sb_buf,
                pSGbuff->sb_len,
                ARG_O_PTR )));
*/
        }

        pBuff = NULL;
    }

    pSG_req->sr_status = ERROR_SUCCESS;
    return TRUE;

READ_ERROR:
    return FALSE;
}

BOOL Fal::WriteToMedia(PSG_REQ pSG_req, BOOL fDoMap)
{
    static PSG_BUF      pSGbuff                     = NULL;
    static PUCHAR       pBuff                       = NULL;

    static DWORD        dwSGBuffNum                  = 0;
    static DWORD        dwSGBuffPos                  = 0;
    static DWORD        dwSectorAddr                = 0;

    static SECTOR_ADDR  physicalSectorAddr          = 0;
    static SECTOR_ADDR  existingPhysicalSectorAddr  = 0;

    static SectorMappingInfo sectorMappingInfo;

    CELOG_WriteSectors(pSG_req->sr_start, pSG_req->sr_num_sec);

    DWORD dwCurSector = pSG_req->sr_start;

    if (m_fReadOnly)
    {
        pSG_req->sr_status = ERROR_WRITE_PROTECT;
        return FALSE;
    }

    //----- 1. Service the sector WRITE request(s) -----
    //         NOTE: The FLASH Media Driver (FMD) is invoked to write the data to the media
    for(dwSGBuffNum=0;
        dwSGBuffNum<pSG_req->sr_num_sg;
        dwSGBuffNum++)
    {
        dwSGBuffPos  = 0;

        // Get a pointer to the scatter/gather buffer
        pSGbuff = &(pSG_req->sr_sglist[dwSGBuffNum]);

/* ctg
        if (fDoMap)
        {
            // Open the sg buffer; performs caller access check.
            if (FAILED (CeOpenCallerBuffer (
                    (PVOID*)&pBuff,
                    pSGbuff->sb_buf,
                    pSGbuff->sb_len,
                    ARG_I_PTR,
                    FALSE )))
            {
                ReportError((TEXT("FLASHDRV.DLL:WriteToMedia() - CeOpenCallerBuffer() failed, couldn't obtain pointer to buffer.\r\n"), 0));
                pSG_req->sr_status = ERROR_INSUFFICIENT_BUFFER;         // Assume CeOpenCallerBuffer() failed because buffer was invalid
                return FALSE;
            }
// need this for 5.0?			pBuff = (PUCHAR)MapCallerPtr(pSGbuff->sb_buf,pSGbuff->sb_len);
        }
        else
*/
        {
            pBuff = pSGbuff->sb_buf;
        }

        DWORD dwNumSectors = pSGbuff->sb_len / g_pFlashMediaInfo->dwDataBytesPerSector;
        DWORD dwError = InternalWriteToMedia (dwCurSector, dwNumSectors, pBuff);

/* ctg
        if (fDoMap)
        {
            // Close the sg buffer.
            VERIFY (SUCCEEDED (CeCloseCallerBuffer (
                pBuff,
                pSGbuff->sb_buf,
                pSGbuff->sb_len,
                ARG_I_PTR )));
        }
*/

        pBuff = NULL;

        if (dwError != ERROR_SUCCESS)
        {
            ReportError((TEXT("FLASHDRV.DLL:WriteToMedia() - InternalWriteToMedia() failed.\r\n")));
            pSG_req->sr_status = dwError;
            return FALSE;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -