?? sddevice.cpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// 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.
//
//
/*++
Module Name:
SDDevice.cpp
Abstract:
SDBus Implementation.
Notes:
--*/
#include <windows.h>
#include <types.h>
#include <creg.hxx>
#include "../HSMMCCh1/s3c6410_hsmmc_lib/sdhcd.h"
#include <cesdbus.h>
#include "../HSMMCCh1/s3c6410_hsmmc_lib/sdcard.h"
#include "sdbus.hpp"
#include "sdslot.hpp"
#include "sdbusreq.hpp"
#include "sddevice.hpp"
#define SD_GET_IO_RW_DIRECT_RESPONSE_FLAGS(pResponse) (pResponse)->ResponseBuffer[SD_IO_R5_RESPONSE_FLAGS_BYTE_OFFSET]
#define SD_GET_IO_RW_DIRECT_DATA(pResponse) (pResponse)->ResponseBuffer[SD_IO_R5_RESPONSE_DATA_BYTE_OFFSET]
DWORD CSDDevice::g_FuncRef = 0 ;
CSDDevice::CSDDevice(DWORD dwFunctionIndex, CSDSlot& sdSlot)
: m_sdSlot(sdSlot)
, m_FuncionIndex(dwFunctionIndex)
{
m_DeviceType = Device_Unknown;
m_RelativeAddress = 0 ;
m_FuncRef = (DWORD)InterlockedIncrement((LPLONG)&g_FuncRef);
m_fAttached = FALSE;
m_pDriverFolder = NULL;
m_hCallbackHandle = NULL;
m_fIsHandleCopied = FALSE;
m_ClientName[0] = 0;
m_ClientFlags = 0;
m_DeviceType=Device_Unknown;
m_pDeviceContext = NULL;
m_pSlotEventCallBack = NULL;
m_RelativeAddress = 0;
m_OperatingVoltage =0 ;
m_pSystemContext = NULL;
// set default access clocks
memset(&m_SDCardInfo,0,sizeof(m_SDCardInfo));
m_SDCardInfo.SDMMCInformation.DataAccessReadClocks = SD_UNSPECIFIED_ACCESS_CLOCKS;
m_SDCardInfo.SDMMCInformation.DataAccessWriteClocks = SD_UNSPECIFIED_ACCESS_CLOCKS;
m_SDCardInfo.SDIOInformation.Function = (UCHAR)dwFunctionIndex;
m_bCardSelectRequest = FALSE;
m_bCardDeselectRequest = FALSE;
m_dwCurSearchIndex = 0;
m_dwCurFunctionGroup = 0 ;
m_hSyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
#ifdef _MMC_SPEC_42_
/**
* Description : to set initial MMC type
*/
m_dwMMCSpecVer = Device_MMC;
memset(m_ucEXTCSD, 0, MMC_EXTCSD_REGISTER_SIZE);
#endif
}
CSDDevice::~CSDDevice()
{
Detach();
if (m_hSyncEvent)
CloseHandle(m_hSyncEvent);
if (m_SDCardInfo.SDIOInformation.pCommonInformation!=NULL) {
if (m_SDCardInfo.SDIOInformation.pCommonInformation->pProductInformation)
delete[] m_SDCardInfo.SDIOInformation.pCommonInformation->pProductInformation;
delete m_SDCardInfo.SDIOInformation.pCommonInformation;
}
}
BOOL CSDDevice::Init()
{
if (!m_hSyncEvent)
return FALSE;
memset(&m_CardInterfaceEx,0,sizeof(m_CardInterfaceEx));
m_CardInterfaceEx.ClockRate = SD_DEFAULT_CARD_ID_CLOCK_RATE;
return TRUE;
}
BOOL CSDDevice::Attach()
{
m_fAttached = TRUE;
return TRUE;
}
BOOL CSDDevice::Detach()
{
Lock();
if (m_fAttached) {
m_fAttached = FALSE;
SDIOConnectDisconnectInterrupt(NULL,FALSE);
SDUnloadDevice();
for (DWORD dwIndex=0; dwIndex<m_dwArraySize ; dwIndex++ ) {
if( m_rgObjectArray[m_dwCurSearchIndex] ) {
// After this point the status should return during the completion.
SDBUS_REQUEST_HANDLE sdBusRequestHandle ;
sdBusRequestHandle.bit.sdBusIndex = m_sdSlot.GetHost().GetIndex();
sdBusRequestHandle.bit.sdSlotIndex = m_sdSlot.GetSlotIndex();
sdBusRequestHandle.bit.sdFunctionIndex = m_FuncionIndex;
sdBusRequestHandle.bit.sdRequestIndex = dwIndex;
sdBusRequestHandle.bit.sd1f = 0x1f;
sdBusRequestHandle.bit.sdRandamNumber =RawObjectIndex(m_dwCurSearchIndex)->GetRequestRandomIndex();
SDFreeBusRequest_I(sdBusRequestHandle.hValue);
}
}
}
Unlock();
return FALSE;
}
SDBUS_DEVICE_HANDLE CSDDevice::GetDeviceHandle()
{
SDBUS_DEVICE_HANDLE retHandle ;
if (m_fAttached) {
retHandle.bit.sdBusIndex = m_sdSlot.GetHost().GetIndex();
retHandle.bit.sdSlotIndex = m_sdSlot.GetSlotIndex();
retHandle.bit.sdFunctionIndex = m_FuncionIndex;
retHandle.bit.sdRandamNumber = m_FuncRef;
retHandle.bit.sdF = SDBUS_DEVICE_HANDLE_FLAG;
}
else
retHandle.hValue = NULL;
return retHandle;
}
BOOL CSDDevice::IsValid20Card()
{
BOOL fValid20Card = FALSE;
if (m_DeviceType!= Device_SD_IO && m_DeviceType != Device_SD_Combo ) {
SD_API_STATUS status = SD_API_STATUS_DEVICE_UNSUPPORTED;
SD_COMMAND_RESPONSE response; // response buffer
// Supported Voltage.
const BYTE fCheckFlags = 0x5a;
BYTE fVHS = (((m_sdSlot.VoltageWindowMask & 0x00f80000)!=0)? 1: 2); // 2.0 / 4.3.13
status = SendSDCommand(SD_CMD_SEND_IF_COND,((DWORD)fVHS<<8)| fCheckFlags , ResponseR7, &response);
if (SD_API_SUCCESS(status)) {
if (response.ResponseBuffer[1]== fCheckFlags && response.ResponseBuffer[2]== fVHS) {
fValid20Card = TRUE;
}
else {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("CSDDevice::DetectSDCard: unusable device found in slot %d , CMD8 response %x, %x \n"),
m_sdSlot.GetSlotIndex(),response.ResponseBuffer[1],response.ResponseBuffer[2]));
status = SD_API_STATUS_DEVICE_UNSUPPORTED ;
}
}
else {//if (SD_API_SUCCESS_RESPONSE_TIMEOUT_OK(status)) // This may cause by SDHC. we have know way to tell.
ASSERT(SD_API_SUCCESS_RESPONSE_TIMEOUT_OK(status));
DEBUGMSG(SDCARD_ZONE_ERROR && !SD_API_SUCCESS_RESPONSE_TIMEOUT_OK(status),
(TEXT("CSDDevice::DetectSDCard: found CMD8 failed in slot %d, please check SDHC make sure to support Response7, SD error =0x%x \n"),m_sdSlot.GetSlotIndex(),status));
status = SD_API_STATUS_SUCCESS;
}
}
return fValid20Card;
}
SD_API_STATUS CSDDevice::DetectSDCard( DWORD& dwNumOfFunct)
{
if (m_FuncionIndex!=0) {
ASSERT(FALSE);
return SD_API_STATUS_DEVICE_UNSUPPORTED;
}
SD_API_STATUS status = SD_API_STATUS_DEVICE_UNSUPPORTED;
SD_COMMAND_RESPONSE response; // response buffer
dwNumOfFunct = 1;
SDCARD_DEVICE_TYPE deviceType = Device_Unknown;
// Detect SD IO Card.
status = SendSDCommand(SD_CMD_IO_OP_COND, 0,ResponseR4,&response);
if (SD_API_SUCCESS_RESPONSE_TIMEOUT_OK(status)) {
if (SD_API_SUCCESS(status)) {
UpdateCachedRegisterFromResponse(SD_INFO_REGISTER_IO_OCR,&response);
DWORD dwNumFunctions = SD_GET_NUMBER_OF_FUNCTIONS(&response);
BOOL fMemoryPresent = SD_MEMORY_PRESENT_WITH_IO(&response);
// Note. dwNumOfFunc does not include function 0. SDIO 3.3
dwNumOfFunct = dwNumFunctions + 1;
if (dwNumFunctions ) {
SetDeviceType(deviceType = (fMemoryPresent? Device_SD_Combo: Device_SD_IO));
status = SetOperationVoltage(Device_SD_IO, TRUE);
if (!SD_API_SUCCESS(status) && fMemoryPresent) {
SetDeviceType(deviceType = Device_Unknown); // Try Memory
status = SD_API_STATUS_SUCCESS;
}
}
else // Only one function.
if (!fMemoryPresent) { // This is unsported.
status = SD_API_STATUS_DEVICE_UNSUPPORTED ;
}
}
else {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: SDIO Card check timeout, moving on \n")));
status = SD_API_STATUS_SUCCESS; // Timeout is OK . we will continue to skan memory.
}
}
// Detect SD MMC
if (SD_API_SUCCESS(status) && (deviceType == Device_Unknown || deviceType == Device_SD_Combo )) { // We have to do other than SD_IO.
// Intiaize
status = SendSDCommand( SD_CMD_GO_IDLE_STATE, 0x00000000, NoResponse, NULL);
BOOL fValid20Card = IsValid20Card();
if (SD_API_SUCCESS(status)) {
if (deviceType != Device_SD_Combo) {
// Detect MMC Card.
#ifdef _MMC_SPEC_42_
/**
* Description : To support MMC SPEC 4.2
*/
status = SendSDCommand( SD_CMD_MMC_SEND_OPCOND,(m_sdSlot.VoltageWindowMask | (1<<30)), ResponseR3, &response);
#else
status = SendSDCommand( SD_CMD_MMC_SEND_OPCOND,m_sdSlot.VoltageWindowMask, ResponseR3, &response);
#endif
if (SD_API_SUCCESS_RESPONSE_TIMEOUT_OK(status)) {
if (SD_API_SUCCESS(status)) {
UpdateCachedRegisterFromResponse( SD_INFO_REGISTER_OCR, &response);
SetDeviceType(deviceType = Device_MMC);
status = SetOperationVoltage(Device_MMC,TRUE);
}
else {
status = SD_API_STATUS_SUCCESS;
}
}
}
// Detect SD Memory
if (SD_API_SUCCESS(status) && (deviceType == Device_Unknown || deviceType == Device_SD_Combo )) { // We Try Memory
// PhiscalLayer 2.0 Table 4-27.
status = SendSDAppCommand( SD_ACMD_SD_SEND_OP_COND, (fValid20Card? (m_sdSlot.VoltageWindowMask | 0x40000000): 0), ResponseR3, &response);
if (SD_API_SUCCESS(status)) {
UpdateCachedRegisterFromResponse( SD_INFO_REGISTER_OCR, &response);
if (deviceType == Device_Unknown)
SetDeviceType(deviceType = Device_SD_Memory);
status = SetOperationVoltage(Device_SD_Memory, deviceType == Device_SD_Memory );
}
}
}
if (!SD_API_SUCCESS(status)){
// check to see what we discovered and post the appropriate error message
if (Device_SD_Combo == deviceType) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: SDIOCombo, Memory portion in slot %d not responsing to ACMD41 \n"), m_sdSlot.GetSlotIndex()));
status = SD_API_STATUS_SUCCESS;
SetDeviceType(deviceType = Device_SD_IO);
} else {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Unknown device found in slot %d \n"),m_sdSlot.GetSlotIndex()));
status = SD_API_STATUS_DEVICE_UNSUPPORTED;
}
}
}
ASSERT(SD_API_SUCCESS(status));
ASSERT(deviceType != Device_Unknown);
return status;
}
CSDBusRequest* CSDDevice::InsertRequestAtEmpty( PDWORD pdwIndex, CSDBusRequest* pObject )
{
if( pObject )
{
Lock();
CSDBusRequest* pReturn = NULL;
DWORD dwStopIndex = m_dwCurSearchIndex;
do {
if( m_rgObjectArray[m_dwCurSearchIndex] == NULL )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -