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

📄 sddevice.cpp

📁 SMDK2416_BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// 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.
//
//
/*++
  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.

  Module Name:  
  SDDevice.cpp
Abstract:
SDBus Implementation.

Notes: 
--*/
#include <windows.h>
#include <types.h>
#include <creg.hxx>

//#include <cesdbus.h>
#if (BSP_TYPE == BSP_SMDK2443)
#include <sdhcd.h>
#include <sdcard.h>

#elif (BSP_TYPE == BSP_SMDK2450)
#include "../SDDriver_INC/sdhcd.h"
#include "../SDDriver_INC/sdcard.h"
#endif

#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_
	/*************************************************************************/
	/****** Date : 07.05.14                                         	******/
	/****** Developer : HS.JANG											******/
	/****** Description : to set initial MMC type						******/
	/*************************************************************************/

	m_dwMMCSpecVer = Device_MMC;
	memset(m_ucEXTCSD,0,512);
	/*************************************************************************/       
#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;
		}
	}
#ifdef _MMC_SPEC_42_
	/*************************************************************************/
	/****** Date : 07.05.14                                         	******/
	/****** Developer : HS.JANG											******/
	/****** Description : Have to know this SD card is SPEC20 or not	******/
	/*************************************************************************/

	m_fValid20Card = fValid20Card;
	/*************************************************************************/    
#endif    
	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_
				/*************************************************************************/
				/****** Date : 07.05.04                                         	******/
				/****** Developer : HS.JANG											******/
				/****** 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 )
				break;
			else if (++m_dwCurSearchIndex>=m_dwArraySize)
				m_dwCurSearchIndex = 0 ;
		} while (dwStopIndex != m_dwCurSearchIndex);

		ASSERT(m_dwCurSearchIndex<m_dwArraySize);
		if( m_dwCurSearchIndex < m_dwArraySize && m_rgObjectArray[m_dwCurSearchIndex] == NULL )  {
			pReturn = m_rgObjectArray[m_dwCurSearchIndex] = pObject;
			pReturn->AddRef();
			if( pdwIndex )
				*( pdwIndex ) = m_dwCurSearchIndex;
		};
		Unlock();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -