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

📄 sdhcslot.cpp

📁 S3C2450BSP开发包,里面有很多资料。可以提供大家参考下。有什么需要解决问题。可以联系我QQ:314661
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  // get the current request  
  pRequest = GetAndLockCurrentRequest();

  if (pRequest) {
    if (!TRANSFER_IS_COMMAND_ONLY(pRequest)) {
      if (UseDmaForRequest(pRequest)) {
        DWORD cbTransfer = TRANSFER_SIZE(pRequest);
        DWORD cbRemainder = cbTransfer % CB_DMA_PAGE;

        if (cbRemainder == 0) {
          cbRemainder = CB_DMA_PAGE;
        }

        pRequest->HCParam += cbRemainder;

        if (TRANSFER_IS_READ(pRequest)) {
          BOOL fNoException;
          DEBUGCHK(cbTransfer <= CB_DMA_BUFFER);

          SD_SET_PROC_PERMISSIONS_FROM_REQUEST(pRequest) {               
            fNoException = SDPerformSafeCopy(pRequest->pBlockBuffer,
                m_pbDmaBuffer, cbTransfer);
          } SD_RESTORE_PROC_PERMISSIONS();

          if (fNoException == FALSE) {
            status = SD_API_STATUS_ACCESS_VIOLATION;
          }
        }
      }
    }

    if (pRequest->HCParam != TRANSFER_SIZE(pRequest)) {
      // This means that a Command Complete interrupt occurred before
      // a Buffer Ready interrupt. Hardware should not allow this. 
      DEBUGCHK(FALSE);
      status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
    }
    RETAILMSG(0, (TEXT("TransferDone, HCParam: %d, TranSize: %d\n"), pRequest->HCParam, TRANSFER_SIZE(pRequest)));

    // complete the request
    if (pRequest->Flags & SD_AUTO_ISSUE_CMD12) {
      m_fAutoCMD12Success = TRUE;
    }

    IndicateBusRequestComplete(pRequest, status);
  }
  // else request must have been canceled due to an error
}


VOID 
CSDHCSlotBase::HandleReadReady(
    )
{
  DEBUGMSG(SDHC_RECEIVE_ZONE, (TEXT("HandleReadReady - HandleReadReady!\n"))); 

  // get the current request  
  PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();

  if (pRequest) {
    DEBUGCHK(!UseDmaForRequest(pRequest));
    DEBUGCHK(pRequest->NumBlocks > 0);
    DEBUGCHK(pRequest->HCParam < TRANSFER_SIZE(pRequest));
    DEBUGCHK(TRANSFER_IS_READ(pRequest));

#ifdef DEBUG
    ++m_dwReadyInts;
#endif

    DWORD dwOldPermissions = SetProcPermissions(pRequest->CurrentPermissions);
    BOOL fKMode = SetKMode( TRUE );

    __try {
      PDWORD pdwUserBuffer = (PDWORD) &pRequest->pBlockBuffer[pRequest->HCParam];
      PDWORD pdwBuffer = pdwUserBuffer;
      DWORD  rgdwIntermediateBuffer[SDHC_MAX_BLOCK_LENGTH / sizeof(DWORD)];
      BOOL   fUsingIntermediateBuffer = FALSE;
      DWORD  cDwords = pRequest->BlockSize / 4;
      DWORD  dwRemainder = pRequest->BlockSize % 4;

      PREFAST_DEBUGCHK(sizeof(rgdwIntermediateBuffer) >= pRequest->BlockSize);

      if (((DWORD) pdwUserBuffer) % 4 != 0) {
        // Buffer is not DWORD aligned so we must use an
        // intermediate buffer.
        pdwBuffer = rgdwIntermediateBuffer;
        fUsingIntermediateBuffer = TRUE;
      }

      DWORD dwDwordsRemaining = cDwords;
      pRequest->HCParam += dwDwordsRemaining * 4;

      // Read the data from the device
      while ( dwDwordsRemaining-- ) {
        *(pdwBuffer++) = ReadDword(SDHC_BUFFER_DATA_PORT_0);
      }

      if ( dwRemainder != 0 ) {
        DWORD dwLastWord = ReadDword(SDHC_BUFFER_DATA_PORT_0);
        memcpy(pdwBuffer, &dwLastWord, dwRemainder);
        pRequest->HCParam += dwRemainder;
      }

      if (fUsingIntermediateBuffer) {
        memcpy(pdwUserBuffer, rgdwIntermediateBuffer, pRequest->BlockSize);
      }

      SetKMode( fKMode );
      SetProcPermissions(dwOldPermissions);
    }
    __except(SDProcessException(GetExceptionInformation())) {
      DEBUGMSG(SDCARD_ZONE_ERROR, (_T("Exception reading from client buffer!\r\n")));
      SetKMode( fKMode );
      SetProcPermissions(dwOldPermissions);
      IndicateBusRequestComplete(pRequest, SD_API_STATUS_ACCESS_VIOLATION);
    }

    DEBUGCHK(pRequest->HCParam == (m_dwReadyInts * pRequest->BlockSize));
  }
  // else request must have been canceled due to an error
}


VOID 
CSDHCSlotBase::HandleWriteReady(
    )
{    
  DEBUGMSG(SDHC_TRANSMIT_ZONE, (TEXT("HandleWriteReady - HandleWriteReady! \n"))); 

  // get the current request  
  PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();

  if (pRequest) {
    DEBUGCHK(TRANSFER_IS_WRITE(pRequest));
    DEBUGCHK(!UseDmaForRequest(pRequest));
    DEBUGCHK(pRequest->NumBlocks > 0);
    DEBUGCHK(pRequest->HCParam < TRANSFER_SIZE(pRequest));

#ifdef DEBUG
    ++m_dwReadyInts;
#endif

    DWORD dwOldPermissions = SetProcPermissions(pRequest->CurrentPermissions);
    BOOL fKMode = SetKMode( TRUE );

    __try {
      PDWORD pdwUserBuffer = (PDWORD) &pRequest->pBlockBuffer[pRequest->HCParam];
      PDWORD pdwBuffer = pdwUserBuffer;
      DWORD  rgdwIntermediateBuffer[SDHC_MAX_BLOCK_LENGTH / sizeof(DWORD)];
      BOOL   fUsingIntermediateBuffer = FALSE;
      DWORD  cDwords = pRequest->BlockSize / 4;
      DWORD  dwRemainder = pRequest->BlockSize % 4;

      PREFAST_DEBUGCHK(sizeof(rgdwIntermediateBuffer) >= pRequest->BlockSize);

      if (((DWORD) pdwUserBuffer) % 4 != 0) {
        // Buffer is not DWORD aligned so we must use an
        // intermediate buffer.
        pdwBuffer = rgdwIntermediateBuffer;
        memcpy(rgdwIntermediateBuffer, pdwUserBuffer, pRequest->BlockSize);
      }

      DWORD dwDwordsRemaining = cDwords;
      pRequest->HCParam += dwDwordsRemaining * 4;

      // Write data to buffer data port
      while ( dwDwordsRemaining-- ) {
        WriteDword(SDHC_BUFFER_DATA_PORT_0, *(pdwBuffer++));
      }

      if ( dwRemainder != 0 ) {
        DWORD dwLastWord = 0;
        memcpy(&dwLastWord, pdwBuffer, dwRemainder);
        WriteDword(SDHC_BUFFER_DATA_PORT_0, dwLastWord);
        pRequest->HCParam += dwRemainder;
      }

      SetKMode( fKMode );
      SetProcPermissions(dwOldPermissions);
    }
    __except(SDProcessException(GetExceptionInformation())) {
      DEBUGMSG(SDCARD_ZONE_ERROR, (_T("Exception reading from client buffer!\r\n")));
      SetKMode( fKMode );
      SetProcPermissions(dwOldPermissions);
      IndicateBusRequestComplete(pRequest, SD_API_STATUS_ACCESS_VIOLATION);
    }

    DEBUGCHK(pRequest->HCParam == (m_dwReadyInts * pRequest->BlockSize));
  }
  // else request must have been canceled due to an error
}


VOID 
CSDHCSlotBase::HandleDma(
    )
{
  // Get the current request
  PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();

  if (pRequest) {
    DEBUGCHK(pRequest->NumBlocks > 0);
    DEBUGCHK(UseDmaForRequest(pRequest));

    DWORD dwNewHCParam = pRequest->HCParam + CB_DMA_PAGE;

    // Only update our transferred count if we have not completed the
    // transfer already, since some host controllers give an extra
    // DMA interrupt after the last block transfer.
    if (dwNewHCParam < TRANSFER_SIZE(pRequest)) {
      pRequest->HCParam = dwNewHCParam;
      DWORD paCurrDmaBuffer = m_paDmaBuffer + pRequest->HCParam;
      DEBUGCHK( paCurrDmaBuffer < (m_paDmaBuffer + CB_DMA_BUFFER) );
      DEBUGCHK( paCurrDmaBuffer < (m_paDmaBuffer + TRANSFER_SIZE(pRequest)) );
      DEBUGCHK( paCurrDmaBuffer == ReadDword(SDHC_SYSTEMADDRESS_LO) );

      WriteDword(SDHC_SYSTEMADDRESS_LO, paCurrDmaBuffer);
    }
  }
  // else request must have been canceled due to an error
}


BOOL 
CSDHCSlotBase::UseDmaForRequest(
    PSD_BUS_REQUEST pRequest
    )
{
  PREFAST_DEBUGCHK(pRequest);

  BOOL fRet = FALSE;

  if (m_pbDmaBuffer) {
    DEBUGCHK(m_paDmaBuffer);

    if ( (pRequest->BlockSize % 4 == 0) &&
        (TRANSFER_SIZE(pRequest) <= CB_DMA_BUFFER) ) {
      DEBUGCHK(m_paDmaBuffer % 4 == 0);
      //DEBUGCHK(PAGE_SIZE == CB_DMA_PAGE);
      DEBUGCHK((PAGE_SIZE*128) == CB_DMA_PAGE);
      fRet = TRUE;
    }
  }

  return fRet;
}


PVOID
CSDHCSlotBase::AllocPhysBuffer(
    size_t cb,
    PDWORD pdwPhysAddr
    )
{
  PVOID pvUncached;
  PVOID pvRet = NULL;
  DWORD dwPhysAddr;

  pvUncached = AllocPhysMem(cb, PAGE_READWRITE, 0, 0, &dwPhysAddr);

  if (pvUncached) {
    *pdwPhysAddr = dwPhysAddr;
    pvRet = pvUncached;
  }

  return pvRet;
}


VOID
CSDHCSlotBase::FreePhysBuffer(
    PVOID pv
    )
{
  BOOL fSuccess;

  DEBUGCHK(pv);

  fSuccess = FreePhysMem(pv);
  DEBUGCHK(fSuccess);
}


VOID
CSDHCSlotBase::SetHardwarePowerState(
    CEDEVICE_POWER_STATE cpsNew
    )
{
  DEBUGCHK(VALID_DX(cpsNew));
  DEBUGCHK(!DX_D1_OR_D2(cpsNew));

  DEBUGCHK(m_cpsCurrent != cpsNew);
  CEDEVICE_POWER_STATE cpsCurrent = m_cpsCurrent;
  m_cpsCurrent = cpsNew;
  BYTE bWakeupControl = m_bWakeupControl;

  if (cpsCurrent == D0) {
    SDClockOff();

    if (cpsNew == D3) {
      if ( m_fSDIOInterruptsEnabled &&  
          (bWakeupControl & WAKEUP_INTERRUPT) ) {
        DEBUGCHK(m_fCardPresent);
        m_fSleepsWithPower = TRUE;
        m_fPowerUpDisabledInts = FALSE;
      }
      else {
        // Wake on status changes only
        WriteByte(SDHC_POWER_CONTROL, 0);
        bWakeupControl &= ~WAKEUP_INTERRUPT;
      }

      // enable wakeup sources
      m_wIntSignals = ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE);
      WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, 0);
      WriteWord(SDHC_NORMAL_INT_STATUS, ReadWord(SDHC_NORMAL_INT_STATUS));
      WriteByte(SDHC_WAKEUP_CONTROL, bWakeupControl);
    }
    else {
      DEBUGCHK(cpsNew == D4);
      WriteByte(SDHC_CLOCK_CONTROL, 0);
      WriteByte(SDHC_POWER_CONTROL, 0);
    }
  }
  else if (cpsCurrent == D3) {
    // Coming out of wakeup state
    if (cpsNew == D0) {            
      WriteByte(SDHC_WAKEUP_CONTROL, 0);

      if (!m_fSleepsWithPower) {
        // Power was turned off to the socket. Re-enumerate card.
        if (m_fCardPresent) {
          HandleRemoval(TRUE);
        }

        m_fCheckSlot = TRUE;
        SetInterruptEvent();
      }
      else {
        if (m_fCardPresent) {
          // Do not do this if the card was removed or 
          // if power was not kept.
          if (m_fPowerUpDisabledInts) {
            EnableSDIOInterrupts(TRUE);
          }
        }
      }

      WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, m_wIntSignals);
    }
    else {
      DEBUGCHK(cpsNew == D4);
      WriteByte(SDHC_CLOCK_CONTROL, 0);
      WriteByte(SDHC_WAKEUP_CONTROL, 0);
      WriteByte(SDHC_POWER_CONTROL, 0);
      WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, m_wIntSignals);
    }

    m_fSleepsWithPower = FALSE;
  }
  else {
    DEBUGCHK(cpsCurrent == D4);

    // Coming out of unpowered state - signal card removal
    // so any card present will be re-enumerated.
    //
    // We do the same thing when we go to D3 as D0 because
    // the slot has lost power so it could have been removed
    // or changed. In other words, D3 is a meaningless state
    // after D4.
    m_cpsCurrent = D0; // Force to D0

    // Do not call HandleRemoval here because it could cause
    // a context switch in a PowerUp callback.
    m_fFakeCardRemoval = TRUE;

    m_fCheckSlot = TRUE;
    SetInterruptEvent();
  }
}


// 08.02.03 by KYS
// In order to prevent infinite CARD INT occuring, below code is needed because of the architecture of HSMMC on s3c6410.
// this process was cop

⌨️ 快捷键说明

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