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

📄 sdhc.cpp

📁 SMDK2416_BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
//
// 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.
//
#endif

// Copyright (c) 2002 BSQUARE Corporation.  All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE

// SDHC controller driver implementation

#if (BSP_TYPE == BSP_SMDK2443)
#include "SDCardDDK.h"

#elif (BSP_TYPE == BSP_SMDK2450)
#include "../../../SDDriver_INC/SDCardDDK.h"
#endif
#include "SDHC.h"


#ifndef SHIP_BUILD
#define STR_MODULE _T("CSDHCBase::")
#define SETFNAME(name) LPCTSTR pszFname = STR_MODULE name _T(":")
#else
#define SETFNAME(name)
#endif

#ifdef DEBUG
#define MAKE_OPTION_STRING(x) _T(#x)

const LPCTSTR CSDHCBase::sc_rgpszOptions[SDHCDSlotOptionCount] = {
    MAKE_OPTION_STRING(SDHCDSetSlotPower),
    MAKE_OPTION_STRING(SDHCDSetSlotInterface),
    MAKE_OPTION_STRING(SDHCDEnableSDIOInterrupts),
    MAKE_OPTION_STRING(SDHCDDisableSDIOInterrupts),
    MAKE_OPTION_STRING(SDHCDAckSDIOInterrupt),
    MAKE_OPTION_STRING(SDHCDGetWriteProtectStatus),
    MAKE_OPTION_STRING(SDHCDQueryBlockCapability),
    MAKE_OPTION_STRING(SDHCDSetClockStateDuringIdle),
    MAKE_OPTION_STRING(SDHCDSetSlotPowerState),
    MAKE_OPTION_STRING(SDHCDGetSlotPowerState),
    MAKE_OPTION_STRING(SDHCDWakeOnSDIOInterrupts),
    MAKE_OPTION_STRING(SDHCDGetSlotInfo),
#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
    MAKE_OPTION_STRING(SDHCDSetSlotInterfaceEx),    
#endif
};
#endif


CSDHCBase::CSDHCBase(
    ) 
: m_regDevice()
{    
  m_hBusAccess = NULL;
  m_cSlots = 0;
  m_pSlots = NULL;
  m_pSlotInfos = NULL;
  m_pHCDContext = NULL;
  m_interfaceType = InterfaceTypeUndefined;
  m_dwBusNumber = INVALID_BUS_NUMBER;
  m_hISRHandler = NULL;
  m_dwSysIntr = SYSINTR_UNDEFINED;
  m_dwPriority = 0;
  m_hevInterrupt = NULL;
  m_htIST = NULL;
  m_cpsCurrent = D0;

  m_fHardwareInitialized = FALSE;
  m_fRegisteredWithBusDriver = FALSE;
  m_fDriverShutdown = FALSE;
  m_fInterruptInitialized = FALSE;
}


CSDHCBase::~CSDHCBase(
    )
{
  // We call PreDeinit just in case we are not being destroyed by
  // a call to SHC_PreDeinit.
  PreDeinit();

  if (m_fHardwareInitialized) {
    DeinitializeHardware();
  }

  if (m_pHCDContext) {
    // Cleanup the host context
    SDHCDDeleteContext(m_pHCDContext);
  }

  if (m_pSlots) delete [] m_pSlots;
  if (m_pSlotInfos) LocalFree(m_pSlotInfos);
  if (m_hBusAccess) CloseBusAccessHandle(m_hBusAccess);
}


BOOL
CSDHCBase::Init(
    LPCTSTR pszActiveKey
    )
{
  BOOL fRet = FALSE;
  SD_API_STATUS status;
  HKEY    hkDevice = NULL;

  hkDevice = OpenDeviceKey(pszActiveKey);
  if (!hkDevice || !m_regDevice.Open(hkDevice, _T(""))) {
    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Failed to open device key\n")));
    goto EXIT;
  }

  // Get a handle to our parent bus.
  m_hBusAccess = CreateBusAccessHandle(pszActiveKey);
  if (m_hBusAccess == NULL) {
    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Could not get handle to parent\n")));
    goto EXIT;
  }

  m_cSlots = DetermineSlotCount();
#if (BSP_TYPE == BSP_SMDK2443)
  if (m_cSlots == 0) {
    goto EXIT;
  }
  ValidateSlotCount();
  RETAILMSG(0,(TEXT("CSDHCBase::Init  m_cSlots=%d\n"),m_cSlots));

#elif (BSP_TYPE == BSP_SMDK2450)
  if (!CheckSlotCount(m_cSlots)) {
    goto EXIT;
  }
  PREFAST_ASSERT(m_cSlots <= SDHC_MAX_SLOTS);
#endif

  m_pSlotInfos = (PSDHC_SLOT_INFO) LocalAlloc(LPTR, 
      sizeof(SDHC_SLOT_INFO) * m_cSlots);
  if (m_pSlotInfos == NULL) {
    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate slot info objects\n")));
    goto EXIT;
  }

  status = SDHCDAllocateContext(m_cSlots, &m_pHCDContext);
  if (!SD_API_SUCCESS(status)) {
    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate context : 0x%08X \n"),
          status));
    goto EXIT;
  }

  // Set our extension 
  m_pHCDContext->pHCSpecificContext = this;

  if (!InitializeHardware()) {
    goto EXIT;
  }
  RETAILMSG(0,(TEXT("AllocateSlotObjects\n")));
  // Allocate slot objects
  m_pSlots = AllocateSlotObjects(m_cSlots);
  if (m_pSlots == NULL) {
    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate slot objects\n")));
    goto EXIT;
  }

  // Initialize the slots
  for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
    PSDHC_SLOT_INFO pSlotInfo = &m_pSlotInfos[dwSlot];
    PCSDHCSlotBase pSlot = GetSlot(dwSlot);

    RETAILMSG(0,(TEXT("pSlot->Init\n")));
    if (!pSlot->Init(dwSlot, pSlotInfo->pucRegisters, m_pHCDContext, 
          m_dwSysIntr, m_hBusAccess, m_interfaceType, m_dwBusNumber, &m_regDevice)) {
      goto EXIT;
    }
  }

  // set the host controller name
  SDHCDSetHCName(m_pHCDContext, TEXT("HSMMC_CH0"));

  // set init handler
  SDHCDSetControllerInitHandler(m_pHCDContext, CSDHCBase::SDHCInitialize);
  // set deinit handler    
  SDHCDSetControllerDeinitHandler(m_pHCDContext, CSDHCBase::SDHCDeinitialize);
  // set the Send packet handler
  SDHCDSetBusRequestHandler(m_pHCDContext, CSDHCBase::SDHCBusRequestHandler);   
  // set the cancel I/O handler
  SDHCDSetCancelIOHandler(m_pHCDContext, CSDHCBase::SDHCCancelIoHandler);   
  // set the slot option handler
  SDHCDSetSlotOptionHandler(m_pHCDContext, CSDHCBase::SDHCSlotOptionHandler);

  // These values must be set before calling SDHCDRegisterHostController()
  // because they are used during that call.
  m_dwPriority = m_regDevice.ValueDW(SDHC_PRIORITY_KEY, 
      SDHC_CARD_CONTROLLER_PRIORITY);
  RETAILMSG(0,(TEXT("SDHCDRegisterHostController\n")));
  // now register the host controller 
  status = SDHCDRegisterHostController(m_pHCDContext);

  if (!SD_API_SUCCESS(status)) {
    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to register host controller: %0x08X \n"), 
          status));
    goto EXIT;
  }

  m_fRegisteredWithBusDriver = TRUE;
  fRet = TRUE;
  RETAILMSG(0,(TEXT("CSDHCBase::Init Finished.\n")));
EXIT:
  if (hkDevice) RegCloseKey(hkDevice);

  return fRet;
}


  SD_API_STATUS
CSDHCBase::Start()
{
  SD_API_STATUS status = SD_API_STATUS_INSUFFICIENT_RESOURCES;

  m_fDriverShutdown = FALSE;

  // allocate the interrupt event
  m_hevInterrupt = CreateEvent(NULL, FALSE, FALSE,NULL);

  if (NULL == m_hevInterrupt) {
    goto EXIT;
  }

  // initialize the interrupt event
  if (!InterruptInitialize (m_dwSysIntr, m_hevInterrupt, NULL, 0)) {
    goto EXIT;
  }

  m_fInterruptInitialized = TRUE;

  // create the interrupt thread for controller interrupts
  m_htIST = CreateThread(NULL, 0, ISTStub, this, 0, NULL);
  if (NULL == m_htIST) {
    goto EXIT;
  }

  for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
    PCSDHCSlotBase pSlot = GetSlot(dwSlot);
    status = pSlot->Start();

    if (!SD_API_SUCCESS(status)) {
      goto EXIT;
    }
  }

  // wake up the interrupt thread to check the slot
  ::SetInterruptEvent(m_dwSysIntr);

  status = SD_API_STATUS_SUCCESS;

EXIT:
  if (!SD_API_SUCCESS(status)) {
    // Clean up
    Stop();
  }

  return status;
}


  SD_API_STATUS
CSDHCBase::Stop()
{
  // Mark for shutdown
  m_fDriverShutdown = TRUE;

  if (m_fInterruptInitialized) {
    KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &m_dwSysIntr, sizeof(m_dwSysIntr),
        NULL, 0, NULL);

    InterruptDisable(m_dwSysIntr);
  }

  // Clean up controller IST
  if (m_htIST) {
    // Wake up the IST
    SetEvent(m_hevInterrupt);
    WaitForSingleObject(m_htIST, INFINITE); 
    CloseHandle(m_htIST);
    m_htIST = NULL;
  }

  // free controller interrupt event
  if (m_hevInterrupt) {
    CloseHandle(m_hevInterrupt);
    m_hevInterrupt = NULL;
  }

  for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
    PCSDHCSlotBase pSlot = GetSlot(dwSlot);
    pSlot->Stop();
  }

  return SD_API_STATUS_SUCCESS;
}


SD_API_STATUS 
CSDHCBase::SlotOptionHandler(
    DWORD                 dwSlot, 
    SD_SLOT_OPTION_CODE   sdOption, 
    PVOID                 pData,
    DWORD                 cbData
    )
{
  SD_API_STATUS   status = SD_API_STATUS_SUCCESS;
  BOOL            fCallSlotsHandler = TRUE;

  Lock();
  Validate();
  PCSDHCSlotBase pSlot = GetSlot(dwSlot);

  DEBUGCHK(sdOption < dim(sc_rgpszOptions));
  DEBUGCHK(sc_rgpszOptions[sdOption] != NULL);
  DEBUGMSG(SDCARD_ZONE_INFO, (_T("CSDHCBase::SlotOptionHandler(%u, %s)\n"),
        dwSlot, sc_rgpszOptions[sdOption]));

  switch (sdOption) {
    case SDHCDSetSlotPower: {
                              if (cbData != sizeof(DWORD)) {
                                status = SD_API_STATUS_INVALID_PARAMETER;
                              }
                              break;
                            }

    case SDHCDSetSlotInterface: {
                                  if (cbData != sizeof(SD_CARD_INTERFACE)) {
                                    status = SD_API_STATUS_INVALID_PARAMETER;
                                  }
                                  break;
                                }

    case SDHCDEnableSDIOInterrupts:
    case SDHCDDisableSDIOInterrupts:
    case SDHCDAckSDIOInterrupt:
                                if (pData || cbData != 0) {
                                  status = SD_API_STATUS_INVALID_PARAMETER;
                                }
                                break;

    case SDHCDGetWriteProtectStatus: {
                                       if (cbData != sizeof(SD_CARD_INTERFACE)) {
                                         status = SD_API_STATUS_INVALID_PARAMETER;
                                       }

⌨️ 快捷键说明

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