📄 falmain.cpp
字号:
}
if (fCombineSg) {
// Combine multiple SG buffers into one if any buffer contains a
// partial sector
sgNew.sr_num_sec = dwTotalSize / g_pFlashMediaInfo->dwDataBytesPerSector;
sgNew.sr_sglist[0].sb_len = dwTotalSize;
sgNew.sr_sglist[0].sb_buf = (BYTE *)LocalAlloc( LPTR, sgNew.sr_sglist[0].sb_len);
if (!sgNew.sr_sglist[0].sb_buf) {
pSG_req->sr_status = GetLastError();
goto READ_ERROR;
}
sgNew.sr_num_sg = 1;
sgNew.sr_start = pSG_req->sr_start;
if (fRet = pFAL->ReadFromMedia(&sgNew, FALSE)) {
// Copy contents read in sgNew back to original sg buffers
pBuff = sgNew.sr_sglist[0].sb_buf;
for(dwSGBuffNum=0; dwSGBuffNum<pSG_req->sr_num_sg; dwSGBuffNum++)
{
LPBYTE pBuff2 = NULL;
/* ctg
// Open the sg buffer; performs caller access check.
if (FAILED (CeOpenCallerBuffer (
(PVOID*)&pBuff2,
pSG_req->sr_sglist[dwSGBuffNum].sb_buf,
pSG_req->sr_sglist[dwSGBuffNum].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
}
else
pBuff2 = (LPBYTE)MapCallerPtr(pSG_req->sr_sglist[dwSGBuffNum].sb_buf,pSG_req->sr_sglist[dwSGBuffNum].sb_len);
if ( pBuff2 )
*/
{
memcpy( pBuff2, pBuff, pSG_req->sr_sglist[dwSGBuffNum].sb_len);
}
pBuff += pSG_req->sr_sglist[dwSGBuffNum].sb_len;
/* ctg
// Close the sg buffer.
VERIFY (SUCCEEDED (CeCloseCallerBuffer (
pBuff2,
pSG_req->sr_sglist[dwSGBuffNum].sb_buf,
pSG_req->sr_sglist[dwSGBuffNum].sb_len,
ARG_O_PTR )));
*/
}
} else {
pSG_req->sr_status = sgNew.sr_status;
}
LocalFree( sgNew.sr_sglist[0].sb_buf);
} else {
fRet = pFAL->ReadFromMedia(pSG_req, TRUE);
}
READ_ERROR:
if (fRet) {
pSG_req->sr_status = ERROR_SUCCESS;
} else {
SetLastError( pSG_req->sr_status);
}
return fRet;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: WriteToMedia()
Description: Performs the specified scatter/gather WRITE request to the media.
Notes: After parsing the parameters, the actual WRITE request is handled
by the FLASH Media Driver (FMD).
Returns: Boolean indicating success.
-------------------------------------------------------------------------------*/
BOOL WriteToMedia(PSG_REQ pSG_req)
{
static PUCHAR pBuff = NULL;
static SG_REQ sgNew;
static DWORD dwSGBuffNum = 0;
DWORD dwTotalSize = 0;
BOOL fRet = FALSE;
BOOL fCombineSg = FALSE;
Fal* pFAL = NULL;
if (!CheckSg (pSG_req, FALSE, &fCombineSg, &dwTotalSize)) {
goto WRITE_ERROR;
}
pFAL = GetFALObject (pSG_req->sr_start, pSG_req->sr_num_sec);
if (!pFAL) {
ReportError((TEXT("FLASHDRV.DLL:WriteToMedia() - GetFALObject failed\r\n")));
pSG_req->sr_status = ERROR_INVALID_PARAMETER;
goto WRITE_ERROR;
}
if (fCombineSg) {
// Combine multiple SG buffers into one if any buffer contains a
// partial sector
sgNew.sr_num_sec = dwTotalSize / g_pFlashMediaInfo->dwDataBytesPerSector;
sgNew.sr_sglist[0].sb_len = dwTotalSize;
sgNew.sr_sglist[0].sb_buf = (BYTE *)LocalAlloc( LPTR, sgNew.sr_sglist[0].sb_len);
if (!sgNew.sr_sglist[0].sb_buf) {
pSG_req->sr_status = GetLastError();
goto WRITE_ERROR;
}
sgNew.sr_num_sg = 1;
sgNew.sr_start = pSG_req->sr_start;
// Copy contents to write from original sg buffers to new sg buffer
pBuff = sgNew.sr_sglist[0].sb_buf;
for(dwSGBuffNum=0; dwSGBuffNum < pSG_req->sr_num_sg; dwSGBuffNum++)
{
LPBYTE pBuff2 = NULL;
/* ctg
// Open the sg buffer; performs caller access check.
if (FAILED (CeOpenCallerBuffer (
(PVOID*)&pBuff2,
pSG_req->sr_sglist[dwSGBuffNum].sb_buf,
pSG_req->sr_sglist[dwSGBuffNum].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
}
else
// need this for 5.0??
pBuff2 = (LPBYTE)MapCallerPtr(pSG_req->sr_sglist[dwSGBuffNum].sb_buf,pSG_req->sr_sglist[dwSGBuffNum].sb_len);
if ( pBuff2 )
*/
{
memcpy( pBuff, pBuff2, pSG_req->sr_sglist[dwSGBuffNum].sb_len);
}
pBuff += pSG_req->sr_sglist[dwSGBuffNum].sb_len;
/* ctg
// Close the sg buffer.
VERIFY (SUCCEEDED (CeCloseCallerBuffer (
pBuff2,
pSG_req->sr_sglist[dwSGBuffNum].sb_buf,
pSG_req->sr_sglist[dwSGBuffNum].sb_len,
ARG_I_PTR )));
*/
}
fRet = pFAL->WriteToMedia(&sgNew, FALSE);
if (!fRet) {
pSG_req->sr_status = sgNew.sr_status;
}
LocalFree( sgNew.sr_sglist[0].sb_buf);
} else {
fRet = pFAL->WriteToMedia(pSG_req, TRUE);
}
WRITE_ERROR:
if (fRet) {
pSG_req->sr_status = ERROR_SUCCESS;
} else {
SetLastError( pSG_req->sr_status);
}
return fRet;
}
BOOL DeleteSectors(PDELETE_SECTOR_INFO pDeleteSectorInfo)
{
Fal* pFal = GetFALObject (pDeleteSectorInfo->startsector, pDeleteSectorInfo->numsectors);
if (!pFal) {
ReportError((TEXT("FLASHDRV.DLL:DeleteSectors() - GetFALObject failed\r\n")));
return FALSE;
}
return pFal->DeleteSectors (pDeleteSectorInfo->startsector, pDeleteSectorInfo->numsectors);
}
BOOL SecureWipe(PDELETE_SECTOR_INFO pDeleteSectorInfo)
{
BOOL fRet = TRUE;
Fal* pFal = GetFALObject (pDeleteSectorInfo->startsector, pDeleteSectorInfo->numsectors);
if (!pFal) {
ReportError((TEXT("FLASHDRV.DLL:SecureWipe() - GetFALObject failed\r\n")));
return FALSE;
}
fRet = pFal->SecureWipe();
pFal->ShutdownFAL();
pFal->StartupFAL(pFal->GetFlashRegion());
return fRet;
}
BOOL SetSecureWipeFlag(PDELETE_SECTOR_INFO pDeleteSectorInfo)
{
Fal* pFal = GetFALObject (pDeleteSectorInfo->startsector, pDeleteSectorInfo->numsectors);
if (!pFal) {
ReportError((TEXT("FLASHDRV.DLL:SetSecureWipeFlag() - GetFALObject failed\r\n")));
return FALSE;
}
return (pFal->SetSecureWipeFlag(INVALID_BLOCK_ID) != INVALID_BLOCK_ID);
}
BOOL FormatMedia(VOID)
{
BOOL fRet = TRUE;
RETAILMSG(1,(TEXT("FormatMedia start:%d\r\n"),GetTickCount() ));
for (DWORD iRegion = 0; iRegion < g_pFlashMediaInfo->dwNumRegions; iRegion++) {
if (g_pFlashMediaInfo->region[iRegion].regionType == FILESYS) {
fRet = g_FalObjects[iRegion]->FormatRegion();
if (!fRet) {
break;
} else {
g_FalObjects[iRegion]->ShutdownFAL();
fRet = g_FalObjects[iRegion]->StartupFAL(&g_pFlashMediaInfo->region[iRegion]);
}
}
}
return fRet;
}
BOOL GetPowerCapabilities(PPOWER_CAPABILITIES ppc)
{
memset (ppc, 0, sizeof(POWER_CAPABILITIES));
ppc->DeviceDx = DX_MASK(D0) | DX_MASK(D4);
return TRUE;
}
BOOL SetPowerState (PCEDEVICE_POWER_STATE pNewPowerState)
{
if (g_CurrentPowerState <= D2 && *pNewPowerState >= D3)
{
// This is going from power on to power off, so wait for
// the compaction threads to finish by entering
// the device critical section
EnterCriticalSection (&g_csFlashDevice);
}
else if (g_CurrentPowerState >= D3 && *pNewPowerState <= D2)
{
// This is going from power off to power on, so leave
// the critical section
LeaveCriticalSection (&g_csFlashDevice);
}
g_CurrentPowerState = *pNewPowerState;
return TRUE;
}
BOOL GetPowerState (PCEDEVICE_POWER_STATE pPowerState)
{
*pPowerState = g_CurrentPowerState;
return TRUE;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: ComputeLog2()
Description: Computes log2 of the specified number. If the specified number
is NOT a power of 2, an error is returned.
Returns: log2 of the specified number; otherwise NOT_A_POWER_OF_2 indicating error.
------------------------------------------------------------------------------*/
UCHAR ComputeLog2(DWORD dwNum)
{
UCHAR log2 = 0;
//----- 1. SPECIAL CASE: 2 raised to any exponent never equals 0 ----
if(dwNum == 0)
{
return NOT_A_POWER_OF_2;
}
//----- 2. Keep dividing by 2 until the LSB is 1 -----
while(!(dwNum & 0x000000001))
{
dwNum >>= 1;
log2++;
}
//----- 3. If (dwNum>>1) != 0, dwNum wasn't a power of 2 -----
if(dwNum>>1)
{
return NOT_A_POWER_OF_2;
}
return log2;
}
BOOL CalculateLogicalRange(PFlashRegion pRegion)
{
DWORD dwBlockID;
DWORD dwNumLogicalBlocks = 0;
RETAILMSG(1,(TEXT("CalculateLogicalRange start:%d\r\n"),GetTickCount() ));
for (dwBlockID = pRegion->dwStartPhysBlock; dwBlockID < pRegion->dwStartPhysBlock + pRegion->dwNumPhysBlocks; dwBlockID++)
{
DWORD dwStatus = FMD.pGetBlockStatus (dwBlockID);
if (!(dwStatus & (BLOCK_STATUS_RESERVED | BLOCK_STATUS_BAD)))
{
dwNumLogicalBlocks++;
}
}
if (dwNumLogicalBlocks <= pRegion->dwCompactBlocks)
{
ReportError((TEXT("FLASHDRV.DLL:CalculateLogicalRange() - Invalid number of logical blocks %d\r\n"), dwNumLogicalBlocks));
return FALSE;
}
// Account for compaction blocks
dwNumLogicalBlocks -= pRegion->dwCompactBlocks;
pRegion->dwNumLogicalBlocks = dwNumLogicalBlocks;
return TRUE;
}
BOOL CalculatePhysRange(PFlashRegion pRegion)
{
DWORD dwBlockID = pRegion->dwStartPhysBlock;
DWORD dwNumLogicalBlocks = 0;
RETAILMSG(1,(TEXT("CalculatePhysRange start:%d\r\n"),GetTickCount() ));
while (dwNumLogicalBlocks < pRegion->dwNumLogicalBlocks)
{
DWORD dwStatus = FMD.pGetBlockStatus (dwBlockID);
if (!(dwStatus & (BLOCK_STATUS_RESERVED | BLOCK_STATUS_BAD)))
{
dwNumLogicalBlocks++;
}
dwBlockID++;
}
if (dwNumLogicalBlocks == 0)
{
ReportError((TEXT("FLASHDRV.DLL:CalculatePhysRange() - Invalid number of logical blocks %d\r\n"), dwNumLogicalBlocks));
return FALSE;
}
pRegion->dwNumPhysBlocks = dwBlockID - pRegion->dwStartPhysBlock + pRegion->dwCompactBlocks;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -