📄 sdslot.cpp
字号:
}
return TRUE;
}
BOOL CSDSlot::Attach()
{
SD_API_STATUS status = m_SdHost.SlotOptionHandler( m_dwSlotIndex, SDHCDGetSlotInfo, (SDCARD_HC_SLOT_INFO *)this, sizeof(SDCARD_HC_SLOT_INFO));
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to get slot info for slot %u\n"), m_dwSlotIndex));
return FALSE;
}
return TRUE;
}
BOOL CSDSlot::Detach()
{
return HandleRemoveDevice();
}
BOOL CSDSlot::HandleAddDevice()
{
// Create Function Zero.
ASSERT(m_pFuncDevice[0]==NULL) ;
BOOL fResult = CSDBusReqAsyncQueue::Init();
ASSERT(fResult);
CSDDevice * psdDevice = new CSDDevice(0, *this);
if (psdDevice && psdDevice->Init() && InsertDevice(0,psdDevice)) {
CSDDevice * psdDevice = GetFunctionDevice(0);
if (psdDevice ) {
psdDevice->Attach();
m_SlotState = SlotIdle ;
DelayForPowerUp();
// Default Value.
memset(&m_SlotInterfaceEx,0,sizeof(m_SlotInterfaceEx));
m_SlotInterfaceEx.ClockRate = SD_DEFAULT_CARD_ID_CLOCK_RATE;
DWORD dwNumOfFunc = 0;
if (SD_API_SUCCESS(SDSetCardInterfaceForSlot(&m_SlotInterfaceEx)) &&
SD_API_SUCCESS(psdDevice->DetectSDCard(dwNumOfFunc))) {
m_AllocatedPower = 0 ;
if (SD_API_SUCCESS ( psdDevice->GetCardRegisters()) &&
SD_API_SUCCESS(psdDevice->DeactivateCardDetect())&&
SD_API_SUCCESS(psdDevice->SDGetSDIOPnpInformation(*psdDevice)) &&
SD_API_SUCCESS(EnumMultiFunction(*psdDevice,dwNumOfFunc ))) {
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // status
for (DWORD dwIndex = 0; dwIndex<dwNumOfFunc && SD_API_SUCCESS(status); dwIndex++) {
CSDDevice * childDevice = GetFunctionDevice(dwIndex);
if (childDevice) {
status = childDevice->SelectCardInterface();
ASSERT(SD_API_SUCCESS(status));
childDevice->DeRef();
}
else
ASSERT(FALSE);
}
if (SD_API_SUCCESS(status))
status = SelectSlotInterface();
ASSERT(SD_API_SUCCESS(status));
for (dwIndex = 0; dwIndex<dwNumOfFunc &&SD_API_SUCCESS(status); dwIndex++) {
CSDDevice * childDevice = GetFunctionDevice(dwIndex);
if (childDevice) {
status = childDevice->SetCardInterface(&m_SlotInterfaceEx);
ASSERT(SD_API_SUCCESS(status));
childDevice->DeRef();
}
else
ASSERT(FALSE);
}
status = SDSetCardInterfaceForSlot(&m_SlotInterfaceEx);
ASSERT(SD_API_SUCCESS(status));
#ifdef _MMC_SPEC_42_
/**
* Description : MMCplus support normaly DAT 8bit bus, but MMCmicro Card dose not Support 8Bit bus, so let bus width down
*/
for (dwIndex = 0; dwIndex<dwNumOfFunc &&SD_API_SUCCESS(status); dwIndex++) {
CSDDevice * childDevice = GetFunctionDevice(dwIndex);
if (childDevice) {
status = childDevice->SetMMCmicroInterface();
ASSERT(SD_API_SUCCESS(status));
childDevice->DeRef();
}
else
ASSERT(FALSE);
}
#endif
if (psdDevice->GetDeviceType() == Device_SD_IO) { // Remove First Function.
psdDevice->SetDeviceType(Device_Unknown);
}
else if (psdDevice->GetDeviceType() == Device_SD_Combo) { // Remove First Function.
psdDevice->SetDeviceType(Device_SD_Memory);
}
/* Start Testing Code.
else if (psdDevice->GetDeviceType() == Device_SD_Memory) { // we do some test
if (Capabilities & SD_SLOT_HIGH_SPEED_CAPABLE) {
SD_CARD_INTERFACE_EX sdCardInterface = m_SlotInterfaceEx;
sdCardInterface.InterfaceModeEx.bit.sdHighSpeed = 1;
SD_API_STATUS status = psdDevice->SDSetCardFeature_I(SD_SET_CARD_INTERFACE_EX, &sdCardInterface, sizeof(sdCardInterface));
ASSERT(SD_API_SUCCESS(status));
}
}
*/
if (SD_API_SUCCESS(status)) {
m_SlotState = SlotInitFailed;
for (dwIndex = 0; dwIndex<dwNumOfFunc; dwIndex++) {
CSDDevice * childDevice = GetFunctionDevice(dwIndex);
DEBUGMSG(ZONE_ENABLE_INFO,(TEXT("HandleAddDevice: LoadDevice type = %d, slot %d"),
(childDevice!=NULL?childDevice->GetDeviceType():Device_Unknown),
m_dwSlotIndex));
if (childDevice && childDevice->GetDeviceType()!=Device_Unknown ) {
status = childDevice->SDLoadDevice();
ASSERT(SD_API_SUCCESS(status));
childDevice->DeRef();
}
}
}
}
}
psdDevice->DeRef();
}
}
else if (psdDevice) {
delete psdDevice;
}
return TRUE;
}
BOOL CSDSlot::HandleRemoveDevice()
{
CSDBusReqAsyncQueue::Detach();
RemoveAllDevice();
ASSERT(m_curHCOwned==NULL);
return TRUE;
}
BOOL CSDSlot::HandleDeviceInterrupting()
{
SD_API_STATUS status = SD_API_STATUS_UNSUCCESSFUL;
if ((m_Flags & SD_SLOT_FLAG_SDIO_INTERRUPTS_ENABLED)!=0) {
CSDDevice * psdDevice = GetFunctionDevice(0);
UCHAR regValue = 0 ;
if (psdDevice) {
// fetch the interrupt pending register
status = psdDevice->SDReadWriteRegistersDirect_I(
SD_IO_READ,
SD_IO_REG_INT_PENDING ,
FALSE,
®Value, // reg
1);
if (SD_API_SUCCESS(status) ) {
regValue &= ~1; // Drop First Bit.
while (regValue) {
UCHAR regValueLowestBit = ((regValue ^ (regValue -1)) & regValue) ;// Detect Lowest Bit.
DWORD dwIndexFunction = 0;
switch (regValueLowestBit) { // For optimize the speed.
default:
ASSERT(FALSE);
case (1<<1):
dwIndexFunction=1;
break;
case (1<<2):
dwIndexFunction=2;
break;
case (1<<3):
dwIndexFunction=3;
break;
case (1<<4):
dwIndexFunction=4;
break;
case (1<<5):
dwIndexFunction=5;
break;
case (1<<6):
dwIndexFunction=6;
break;
case (1<<7):
dwIndexFunction=7;
break;
}
regValue &= ~regValueLowestBit;
CSDDevice * psdSubDevice = GetFunctionDevice(dwIndexFunction);
if (psdSubDevice) {
psdSubDevice->HandleDeviceInterrupt();
psdSubDevice->DeRef();
}
else
ASSERT(FALSE);
}
}
psdDevice->DeRef();
}
}
// Ack Interupt
GetHost().SlotOptionHandler(m_dwSlotIndex,SDHCDAckSDIOInterrupt,NULL,0);
return TRUE;
}
// Enumerate multi function card.
SD_API_STATUS CSDSlot::EnumMultiFunction(CSDDevice& psdDevice0,DWORD dwNumOfFunc )
{
SD_API_STATUS status; // status
UCHAR currentFunction; // current function
BOOL isCombo = FALSE; // is combo device flag
// check the base type for multifunction or combo device
if (Device_SD_IO ==psdDevice0.GetDeviceType() || Device_SD_Combo == psdDevice0.GetDeviceType()) {
ASSERT(dwNumOfFunc >= 2);
// set up functions 1..7, if present for the parent device
for (currentFunction = 1;currentFunction < dwNumOfFunc; currentFunction++) {
// create SDIO child devices for this parent
status = CreateChildDevice( Device_SD_IO, currentFunction, psdDevice0);
if (SD_API_SUCCESS(status)) {
CSDDevice * pChildDevice = GetFunctionDevice(currentFunction);
if (pChildDevice) {
status = pChildDevice->SDGetSDIOPnpInformation(psdDevice0);
if (SD_API_SUCCESS(status)) {
pChildDevice->SetupWakeupSupport();
}
pChildDevice->DeRef();
}
else {
status = SD_API_STATUS_UNSUCCESSFUL;
}
}
if (!SD_API_SUCCESS(status)) {
ASSERT(FALSE);
return status;
}
}
return SD_API_STATUS_SUCCESS;
}
else {
return SD_API_STATUS_SUCCESS;
}
}
SD_API_STATUS CSDSlot::CreateChildDevice(SDCARD_DEVICE_TYPE sdCard_DeviceType, DWORD dwFunctionIndex, CSDDevice& psdDevice0)
{
SD_API_STATUS status = SD_API_STATUS_INVALID_PARAMETER;
CSDDevice* pNewDevice = new CSDDevice(dwFunctionIndex,*this);
if (pNewDevice && pNewDevice->Init() && InsertDevice(dwFunctionIndex, pNewDevice)) {
CSDDevice * psdDevice = GetFunctionDevice(dwFunctionIndex);
if (psdDevice) {
if (m_SdHost.IsAttached()) {
psdDevice->Attach();
psdDevice->CopyContentFromParent(psdDevice0);
psdDevice->SetDeviceType(sdCard_DeviceType);
}
psdDevice->DeRef();
status = SD_API_STATUS_SUCCESS ;
}
}
else {
ASSERT(FALSE);
if (pNewDevice)
delete pNewDevice;
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
}
ASSERT(SD_API_SUCCESS(status));
return status;
}
BOOL CSDSlot::CancelRequestFromHC(CSDBusRequest * pRequest)
{
BOOL fRetrun = FALSE;
m_SdHost.SDHCAccessLock();
DEBUGMSG(SDCARD_ZONE_0,(TEXT("CancelRequestFromHC(%x)"),pRequest));
if (m_SdHost.IsAttached() && m_curHCOwned && m_lcurHCLockCount == 0 && pRequest == m_curHCOwned) {
fRetrun = m_SdHost.CancelIOHandler(m_dwSlotIndex, pRequest );
}
m_SdHost.SDHCAccessUnlock();
return fRetrun;
}
BOOL CSDSlot::CompleteRequestFromHC(CSDBusRequest * pRequest,SD_API_STATUS status)
{
BOOL fRetrun = FALSE;
m_SdHost.SDHCAccessLock();
DEBUGMSG(SDCARD_ZONE_0,(TEXT("CompleteRequestFromHC(%x,%x)\n"),pRequest,status));
if ( m_curHCOwned && pRequest == m_curHCOwned) {
m_curHCOwned = NULL;
m_lcurHCLockCount = 0 ;
CompleteRequest(pRequest, status );
fRetrun = TRUE;
}
else {
ASSERT(FALSE);
}
m_SdHost.SDHCAccessUnlock();
return fRetrun;
}
CSDBusRequest * CSDSlot::SDHCGetAndLockCurrentRequest_I()
{
CSDBusRequest * pReturn = NULL;
m_SdHost.SDHCAccessLock();
DEBUGMSG(SDCARD_ZONE_0,(TEXT("SDHCGetAndLockCurrentRequest_I,m_curHCOwned=%x\n"),m_curHCOwned));
if (m_curHCOwned) {
m_lcurHCLockCount++;
pReturn = m_curHCOwned;
}
m_SdHost.SDHCAccessUnlock();
return pReturn;
}
void CSDSlot::SDHCDUnlockRequest_I(PSD_BUS_REQUEST hReques)
{
m_SdHost.SDHCAccessLock();
DEBUGMSG(SDCARD_ZONE_0,(TEXT("SDHCDUnlockRequest_I(%x), m_curHCOwned=%x\n"),hReques,m_curHCOwned));
if (m_curHCOwned!=NULL && m_curHCOwned == hReques && m_lcurHCLockCount) {
m_lcurHCLockCount--;
}
m_SdHost.SDHCAccessUnlock();
};
///////////////////////////////////////////////////////////////////////////////
// This routine is calling from seperate working thread.
VOID CSDSlot::SlotStatusChangeProcessing(SD_SLOT_EVENT Event)
///////////////////////////////////////////////////////////////////////////////
{
switch (Event) {
case DeviceInterrupting:
HandleDeviceInterrupting();
break;
case DeviceInserted:
HandleAddDevice();
break;
case DeviceEjected:
HandleRemoveDevice();
break;
case SlotDeselectRequest:
case SlotSelectRequest:
case SlotResetRequest:
HandleSlotSelectDeselect(Event);
break;
default:
DEBUG_CHECK(FALSE, (TEXT("SDBusDriver: SlotStatusChange Unknown Slot Event : %d \n"),Event));
break;
}
}
///////////////////////////////////////////////////////////////////////////////
// SlotStateChange - indicate a change in the SD Slot
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -