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

📄 sdmemdiskio.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            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 + -