📄 sdbusrequest.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
// Copyright (c) 2002-2004 BSQUARE Corporation. All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE
// Bus request api implementation
#include <SDCardDDK.h>
#include "SDbusdriver.h"
#include <celog.h>
#ifdef SD_SPEC_20
/*************************************************************************/
/****** Date : 07.05.04 ******/
/****** Developer : HS.JANG ******/
/****** Description : It has to know that SDcard inserted is in ******/
/****** which slot ( It is needed on SMDK2443 ******/
/*************************************************************************/
#define GET_HC_NAME_FROM_SLOT(s) (s)->pHostController->HostControllerName // added by JJG 06.11.17
/*************************************************************************/
#endif
#ifdef DEBUG
// card response text look up
static const WCHAR *SDCardResponseTypeLookUp[8] =
{{TEXT("NoResponse")},
{TEXT("R1")},
{TEXT("R1b")},
{TEXT("R2")},
{TEXT("R3")},
{TEXT("R4")},
{TEXT("R5")},
{TEXT("R6")}
};
// card state string look up
static const WCHAR *SDCardStateStringLookUp[16] =
{{TEXT("IDLE")},
{TEXT("READY")},
{TEXT("IDENT")},
{TEXT("STBY")},
{TEXT("TRAN")},
{TEXT("DATA")},
{TEXT("RCV")},
{TEXT("PRG")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
};
#endif
#ifdef SD_SPEC_20
/*************************************************************************/
/****** Date : 07.05.04 ******/
/****** Developer : HS.JANG ******/
/****** Description : It has to know that SDcard inserted supports ******/
/****** SD high capacity ******/
/*************************************************************************/
extern int g_bIsSupportSDHC;
/*************************************************************************/
#endif
///////////////////////////////////////////////////////////////////////////////
// CopyResponseToSynchInfo
// Input: pSynchInfo - the synch info that will receive the response
// pRequest - the request that just completed that contains the respose
// Output: FALSE if there was an exception
// Notes:
///////////////////////////////////////////////////////////////////////////////
BOOL CopyResponseToSynchInfo(__out PSD_SYNCH_REQUEST_INFO pSynchInfo,
const SDBUS_BUS_REQUEST *pRequest)
{
BOOL fNoException;
// we are copying data back from an arbitrary context, set access permissions
SD_SET_PROC_PERMISSIONS_FROM_REQUEST(pRequest) {
// copy the response buffer
fNoException = SDPerformSafeCopy(pSynchInfo->pResponse,
&pRequest->CommandResponse, sizeof(SD_COMMAND_RESPONSE));
} SD_RESTORE_PROC_PERMISSIONS();
if (fNoException == FALSE) {
DEBUGMSG(SDCARD_ZONE_ERROR,
(TEXT("SDBusDriver: Exception writing to response buffer\n")));
pSynchInfo->Status = SD_API_STATUS_ACCESS_VIOLATION;
}
return fNoException;
}
///////////////////////////////////////////////////////////////////////////////
// SDSynchCommandCompleteCallback - synchronous completion callback
// Input: hDevice - the device handle
// pRequest - the request that just completed
// pContext - the context passed in register device
// BusRequestParam - the optional argument
// Output:
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID SDSynchCommandCompleteCallback(SD_DEVICE_HANDLE hDevice,
HBUS_REQUEST hRequest,
PVOID pContext,
DWORD BusRequestParam)
{
PSD_SYNCH_REQUEST_INFO pSynchInfo = (PSD_SYNCH_REQUEST_INFO)BusRequestParam;
PSDBUS_BUS_REQUEST pRequest = (PSDBUS_BUS_REQUEST) hRequest;
// save off the status
pSynchInfo->Status = pRequest->Status;
if (NULL != pSynchInfo->pResponse) {
CopyResponseToSynchInfo(pSynchInfo, pRequest);
}
// free this request
SDFreeBusRequest__X(hRequest);
// wake up the blocked thread
SetEvent(pSynchInfo->hWaitEvent);
}
///////////////////////////////////////////////////////////////////////////////
// SDSynchronousBusRequest__X - send an SD Bus request synchronously
// Input: hDevice - device handle
// Command - command to send
// Argument - argument for command
// TransferClass - Command only, or associated with read/write data
// ResponseType - expected response
// pResponse - buffer to hold response (OPTIONAL)
// NumBlocks - number of blocks
// BlockSize - block size
// pBuffer - block buffer
// Flags - bus request flags
//
// Output: pResponse - caller allocated storage for the return response
// Return: SD_API_STATUS
// Notes:
// This function provides a synchronous (blocking) call to perform a
// bus request.
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDSynchronousBusRequest__X(SD_DEVICE_HANDLE hDevice,
UCHAR Command,
DWORD Argument,
SD_TRANSFER_CLASS TransferClass,
SD_RESPONSE_TYPE ResponseType,
PSD_COMMAND_RESPONSE pResponse,
ULONG NumBlocks,
ULONG BlockSize,
PUCHAR pBuffer,
DWORD Flags)
{
SD_API_STATUS status; // intermediate status
PSD_SYNCH_REQUEST_INFO pSynchInfo; // synch information
HBUS_REQUEST hRequest; // the new request
DWORD waitResult; // wait result
CSDBusDriver *pBusDriver; // the bus driver
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: SendSynchCommandRequest+\n")));
PSDCARD_DEVICE_CONTEXT pDevice = (PSDCARD_DEVICE_CONTEXT) hDevice;
if (!ValidateClientHandle(pDevice)) {
return SD_API_STATUS_INVALID_HANDLE;
}
DEBUGCELOGMSG(SDCARD_ZONESLOT_CELOG,(TEXT("+SDSynchronousBusRequest__X(Command=%x,Argument=%x,NumBlocks=%x,BlockSize=%x\r\n"),
(DWORD)Command,Argument,NumBlocks,BlockSize));
EnterCriticalSection(&pDevice->syncCritSection);
ASSERT(pDevice->syncCount==0);
pDevice->syncCount++;
ResetEvent(pDevice->synchInfo.hWaitEvent);
// get the bus driver
pBusDriver = SDDCGetBusDriver(pDevice);
// allocate a synch info structure, we pre-allocate event objects to
// minimize impact of creating and deleting wait objects
pSynchInfo = &pDevice->synchInfo;
// save the response
pSynchInfo->pResponse = pResponse;
// send the request
status = SDBusRequest__X(hDevice, // device
Command, // command
Argument, // command argument
TransferClass, //
ResponseType, // response
NumBlocks, // no blocks
BlockSize, //
pBuffer, //
SDSynchCommandCompleteCallback, // callback
(DWORD)pSynchInfo, // pass the synch information
&hRequest, // request
(( 0 == ( pDevice->SDCardInfo.SDIOInformation.Flags & FSTPTH_DISABLE )) ? SD_SYNCHRONOUS_REQUEST : 0 ) |
Flags); // flags
/*====================================================================================================
-----------------------------------------------------------------------------------------
Normal-Path
-----------------------------------------------------------------------------------------
Client Driver Thread Interrupt Thread Dispatcher Thread
(Host Controller Driver) (SDBusDriver)
|
v
calls SDSynchronousBusRequest
+-- |
| v
| D Build Bus Request
| r |
|B i v
|u v Place in Bus Request Queue
|s e |
| r v
| Start first bus request
+-- |
| v
|H Start I/O on controller
|o which will generate interrupt ->+-> Wait for Interrupt Event
|s | ^ |
|t v | v
| return pending status | Complete I/O operation
|C D | | |
|o r | | v
|n i | | Move request to completion queue .---------------.
|t v | | | | |
|r e | | v v |
|o r | | Notify Dispatcher Wait for Event |
|l | | | | |
|l | | v v |
|e | | Start next request Get request from |
|r | | | completion queue |
| | `-----------' | |
| | v |
+ | Call callback handler |
| D | | |
| r v v |
|B i Wait For I/O Completion <-------------------------------------- Set I/O completion event|
|u v | | |
|s e v v |
| r Return final status Free request |
| | |
+-- `---------------'
====================================================================================================*/
// Wait for the host controller to complete the request processing.
if ( SD_API_STATUS_FAST_PATH_SUCCESS != status )
{
if (!SD_API_SUCCESS(status)) {
DbgPrintZo(SDCARD_ZONE_FUNC, (TEXT("SDCard: SendSynchCommandRequest-\n")));
//pBusDriver->FreeSyncInfo(pSynchInfo);
pDevice->syncCount--;
LeaveCriticalSection(&pDevice->syncCritSection);
return status;
}
// wait for the I/O to complete
waitResult = WaitForSingleObject(pSynchInfo->hWaitEvent, INFINITE);
if (WAIT_OBJECT_0 == waitResult) {
// the request finishes asynchronously and the callback updated the status in the synch struct
status = pSynchInfo->Status;
} else {
DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: SendSynchCommandRequest - Wait Failed 0x%08X \n"),waitResult));
// cancel the bus request
SDCancelBusRequest__X(hRequest);
status = SD_API_STATUS_UNSUCCESSFUL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -