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

📄 sdslot.cpp

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