📄 fal.cpp
字号:
//
// 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 + -