📄 sdmemdiskio.cpp
字号:
NumBlocks*SD_BLOCK_SIZE));
status = ERROR_GEN_FAILURE;
goto statusReturn;
}
// get block transfer buffer
pBlockBuffer = (PUCHAR)SDAllocateFromMemList(pMemCard->hBufferList);
// initialize some variables used in data copy
SGBufNum = 0;
SGBufRemaining = pSG->sr_sglist[SGBufNum].sb_len;
// open the first sg buffer
if (FAILED (CeOpenCallerBuffer (
(void**)&pSGBuffer,
pSG->sr_sglist[SGBufNum].sb_buf,
pSG->sr_sglist[SGBufNum].sb_len,
ARG_O_PTR,
FALSE
))) {
status = ERROR_INVALID_PARAMETER;
goto statusReturn;
}
pSGBufferCursor = pSGBuffer;
// split the reads into groups of TransferBlockSize in size to avoid
// hogging the SD Bus with large reads
for (PartialStartBlock = StartBlock; PartialStartBlock < StartBlock+NumBlocks; PartialStartBlock += pMemCard->BlockTransferSize) {
// some variables just used for copying
DWORD PartialTransferSize;
DWORD CopySize;
pCardDataPtr = pBlockBuffer;
PartialTransferSize = MIN(
pMemCard->BlockTransferSize,
StartBlock+NumBlocks-PartialStartBlock);
// read the data from SD Card
status = SDMemReadMultiple(
pMemCard,
PartialStartBlock,
PartialTransferSize,
pBlockBuffer);
if (status != ERROR_SUCCESS) {
break;
}
// copy from pBlockArray to pSG buffers
CardDataRemaining = PartialTransferSize*SD_BLOCK_SIZE;
while (CardDataRemaining) {
// get minimum of remaining size in SG buf and data left in pBlockBuffer
CopySize = MIN(SGBufRemaining, CardDataRemaining);
// copy that much data to SG buffer
if (0 == CeSafeCopyMemory(pSGBufferCursor, pCardDataPtr, CopySize)) {
status = ERROR_INVALID_PARAMETER;
goto statusReturn;
}
// update pointers and counts
pSGBufferCursor += CopySize;
pCardDataPtr += CopySize;
CardDataRemaining -= CopySize;
SGBufRemaining -= CopySize;
// fet the next SG Buffer if needed
if (!SGBufRemaining && CardDataRemaining) {
// close the current sg buffer
VERIFY (SUCCEEDED (CeCloseCallerBuffer (
pSGBuffer,
pSG->sr_sglist[SGBufNum].sb_buf,
pSG->sr_sglist[SGBufNum].sb_len,
ARG_O_PTR
)));
// open the next sg buffer
SGBufNum++;
SGBufRemaining = pSG->sr_sglist[SGBufNum].sb_len;
if (FAILED (CeOpenCallerBuffer (
(void**)&pSGBuffer,
pSG->sr_sglist[SGBufNum].sb_buf,
pSG->sr_sglist[SGBufNum].sb_len,
ARG_O_PTR,
FALSE
))) {
status = ERROR_INVALID_PARAMETER;
goto statusReturn;
}
pSGBufferCursor = pSGBuffer;
}
}
}
// close the final sg buffer
VERIFY (SUCCEEDED (CeCloseCallerBuffer (
pSGBuffer,
pSG->sr_sglist[SGBufNum].sb_buf,
pSG->sr_sglist[SGBufNum].sb_len,
ARG_O_PTR
)));
statusReturn:
// free the allocated block buffer
if(pBlockBuffer) {
SDFreeToMemList(pMemCard->hBufferList, pBlockBuffer);
}
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDMemory: -SDMemRead\r\n")));
// FATFS wants the status returned in the SG buffers also
pSG->sr_status = status;
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDMemWrite - Write data to card from pSG scatter gather buffers
// Input: pMemCard - SD memory card structure
// pSG - Scatter Gather buffer structure from FATFS
// Output:
// Return: Status - windows status code
// Notes: Writes to the card are split into groups of size TransferBlockSize
// This is controlled by a registry entry for the driver.
///////////////////////////////////////////////////////////////////////////////
DWORD SDMemWrite( PSD_MEMCARD_INFO pMemCard, PSG_REQ pSG )
{
DWORD NumBlocks;
DWORD StartBlock;
PUCHAR pBlockBuffer = NULL, pCardDataPtr = NULL;
PUCHAR pSGBuffer = NULL;
PUCHAR pSGBufferCursor = NULL;
DWORD status = ERROR_SUCCESS;
DWORD SGBufNum, SGBufLen, SGBufRemaining;
DWORD PartialStartBlock;
DWORD CardDataRemaining;
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDMemory: +SDMemWrite\r\n")));
PREFAST_DEBUGCHK(pSG);
// pSG is a sterile SG_REQ copy of the callers's SG_REQ; we can map the
// embedded pointers back into it
// validate the embedded sb_bufs
for (ULONG ul = 0; ul < pSG->sr_num_sg; ul += 1) {
if (
(NULL == pSG->sr_sglist[ul].sb_buf) ||
(0 == pSG->sr_sglist[ul].sb_buf)
) {
status = ERROR_INVALID_PARAMETER;
goto statusReturn;
}
}
// validate the I/O request
if ((pSG->sr_start > pSG->sr_start + pSG->sr_num_sec)
||(pSG->sr_start + pSG->sr_num_sec) > pMemCard->DiskInfo.di_total_sectors) {
status = ERROR_INVALID_PARAMETER;
goto statusReturn;
}
// check card write protect status
if (pMemCard->WriteProtected) {
DEBUGMSG(SDMEM_ZONE_DISK_IO, (TEXT("SDMemWrite: Card is write protected\r\n")));
status = ERROR_WRITE_PROTECT;
goto statusReturn;
}
// get number of sectors
StartBlock = pSG->sr_start;
NumBlocks = pSG->sr_num_sec;
// cannot read more than 4GB at a time or SGBufLen will overflow
if (ULONG_MAX / SD_BLOCK_SIZE < NumBlocks) {
status = ERROR_INVALID_PARAMETER;
goto statusReturn;
}
DEBUGMSG(SDMEM_ZONE_DISK_IO, (TEXT("SDMemWrite: Writing blocks %d-%d\r\n"),
StartBlock,
StartBlock+NumBlocks-1));
// calculate total buffer space of scatter gather buffers
SGBufLen = 0;
for (SGBufNum = 0; SGBufNum < pSG->sr_num_sg; SGBufNum++) {
SGBufLen += pSG->sr_sglist[SGBufNum].sb_len;
}
// check total SG buffer space is enough for reqeusted transfer size
if(SGBufLen < NumBlocks * SD_BLOCK_SIZE) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDMemWrite: SG Buffer space %d bytes less than block write size %d bytes\r\n"),
SGBufLen,
NumBlocks * SD_BLOCK_SIZE));
status = ERROR_GEN_FAILURE;
goto statusReturn;
}
// get block transfer buffer
pBlockBuffer = (PUCHAR)SDAllocateFromMemList(pMemCard->hBufferList);
// initialize some variables used in data copy
SGBufNum = 0;
SGBufRemaining = pSG->sr_sglist[SGBufNum].sb_len;
// open the first sg buffer
if (FAILED (CeOpenCallerBuffer (
(void**)&pSGBuffer,
pSG->sr_sglist[SGBufNum].sb_buf,
pSG->sr_sglist[SGBufNum].sb_len,
ARG_I_PTR,
FALSE
))) {
status = ERROR_INVALID_PARAMETER;
goto statusReturn;
}
pSGBufferCursor = pSGBuffer;
// split the writes into groups of TransferBlockSize in size to avoid
// hogging the SD Bus with large writes
for(PartialStartBlock = StartBlock; PartialStartBlock < StartBlock+NumBlocks; PartialStartBlock += pMemCard->BlockTransferSize) {
// some variables just used for copying
DWORD PartialTransferSize;
DWORD CopySize;
pCardDataPtr = pBlockBuffer;
PartialTransferSize = MIN(
pMemCard->BlockTransferSize,
StartBlock+NumBlocks-PartialStartBlock);
// copy from pSG buffers to pBlockArray
CardDataRemaining = PartialTransferSize*SD_BLOCK_SIZE;
while (CardDataRemaining) {
// get minimum of remaining size in SG buf and data left in pBlockBuffer
CopySize = MIN(SGBufRemaining, CardDataRemaining);
// copy that much data to block buffer
if (0 == CeSafeCopyMemory(pCardDataPtr, pSGBufferCursor, CopySize)) {
status = ERROR_INVALID_PARAMETER;
goto statusReturn;
}
// update pointers and counts
pSGBufferCursor += CopySize;
pCardDataPtr += CopySize;
CardDataRemaining -= CopySize;
SGBufRemaining -= CopySize;
// get the next SG Buffer if needed
if (!SGBufRemaining && CardDataRemaining) {
// close the current sg buffer
VERIFY (SUCCEEDED (CeCloseCallerBuffer (
pSGBuffer,
pSG->sr_sglist[SGBufNum].sb_buf,
pSG->sr_sglist[SGBufNum].sb_len,
ARG_I_PTR
)));
// open the next sg buffer
SGBufNum++;
SGBufRemaining = pSG->sr_sglist[SGBufNum].sb_len;
if (FAILED (CeOpenCallerBuffer (
(void**)&pSGBuffer,
pSG->sr_sglist[SGBufNum].sb_buf,
pSG->sr_sglist[SGBufNum].sb_len,
ARG_I_PTR,
FALSE
))) {
status = ERROR_INVALID_PARAMETER;
goto statusReturn;
}
pSGBufferCursor = pSGBuffer;
}
}
// write the data to the SD Card
status = SDMemWriteMultiple(
pMemCard,
PartialStartBlock,
PartialTransferSize,
pBlockBuffer);
if (status != ERROR_SUCCESS) {
break;
}
}
// close the final sg buffer
VERIFY (SUCCEEDED (CeCloseCallerBuffer (
pSGBuffer,
pSG->sr_sglist[SGBufNum].sb_buf,
pSG->sr_sglist[SGBufNum].sb_len,
ARG_I_PTR
)));
statusReturn:
// free the allocated block buffer
if (pBlockBuffer) {
SDFreeToMemList(pMemCard->hBufferList, pBlockBuffer);
}
// FATFS wants the status returned in the SG buffers also
pSG->sr_status = status;
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDMemory: -SDMemWrite\r\n")));
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDMemErase - Erase a contiguous set of blocks
// Input: pMemCard - SD memory card structure
// pDSI - structure describing the range of sectors to erase
// Output:
// Return: Status - windows status code
// Notes:
///////////////////////////////////////////////////////////////////////////////
DWORD SDMemErase( PSD_MEMCARD_INFO pMemCard, PDELETE_SECTOR_INFO pDSI )
{
DWORD dwStatus = ERROR_NOT_SUPPORTED;
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDMemory: +SDMemErase\n")));
PREFAST_DEBUGCHK(pMemCard);
PREFAST_DEBUGCHK(pDSI);
// Validate Gather request
if ((pDSI->startsector + pDSI->numsectors) > pMemCard->DiskInfo.di_total_sectors) {
dwStatus = ERROR_INVALID_PARAMETER;
goto statusReturn;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -