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

📄 sdcontrol.c

📁 老外的一个开源项目
💻 C
📖 第 1 页 / 共 5 页
字号:
SD_API_STATUS SDInitialize(PSDCARD_HC_CONTEXT pHCContext)
{
    DWORD dwSDIOIrq;
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;   // intermediate status
    DWORD         threadID;                         // thread ID
    PSDH_HARDWARE_CONTEXT pHardwareContext;       // hardware context
    PHYSICAL_ADDRESS SDMMC_Base = {PXA255_BASE_REG_PA_MMC};
    PHYSICAL_ADDRESS DMA_Base = {PXA255_BASE_REG_PA_DMAC};

    pHardwareContext = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

    InitializeCriticalSection(&pHardwareContext->ControllerCriticalSection);

    pHardwareContext->fSDIOEnabled = FALSE;
    pHardwareContext->fSDIOInterruptPending = FALSE;
    pHardwareContext->DevicePresent = FALSE;


	if( !InitializeHardware() )
    {
		DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error initializing platform specific hardware\r\n")));
        return SD_API_STATUS_INSUFFICIENT_RESOURCES;
    }

	pHardwareContext->pSDMMCRegisters = (MMC_REG_T *)MmMapIoSpace( SDMMC_Base, 0x400, FALSE );
	if ( !pHardwareContext->pSDMMCRegisters )
	{
		DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error allocating SD/MMC registers\r\n")));
        goto exitInit;
	}

	pHardwareContext->pDMARegisters = (DMAC_REG_T *)MmMapIoSpace( DMA_Base, 0x400, FALSE );
	if ( !pHardwareContext->pDMARegisters )
	{
		DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error allocating DMA control registers\r\n")));
        goto exitInit;
	}

#ifdef DEBUG
    DumpRegisters( pHardwareContext );
#endif

    // allocate the interrupt event
    pHardwareContext->hControllerInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
    
    if (NULL == pHardwareContext->hControllerInterruptEvent) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }
        // convert the hardware SD/MMC controller interrupt IRQ into a logical SYSINTR value
    dwSDIOIrq = pHardwareContext->dwSDMMCIrq;
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwSDIOIrq, sizeof(DWORD), &(pHardwareContext->dwSysintrSDMMC), sizeof(DWORD), NULL))
    {
        // invalid SDIO SYSINTR value!
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("Error obtaining SDIO SYSINTR value!\n")));
        pHardwareContext->dwSysintrSDMMC = SYSINTR_UNDEFINED;
        goto exitInit;
    }

        // initialize the interrupt event
    if (!InterruptInitialize (pHardwareContext->dwSysintrSDMMC,
                              pHardwareContext->hControllerInterruptEvent,
                              NULL,
                              0)) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    pHardwareContext->DriverShutdown = FALSE;
    
        // create the interrupt thread for controller interrupts
    pHardwareContext->hControllerInterruptThread = CreateThread(NULL,
                                                      0,
                                                      (LPTHREAD_START_ROUTINE)SDControllerIstThread,
                                                      pHardwareContext,
                                                      0,
                                                      &threadID);

    if (NULL == pHardwareContext->hControllerInterruptThread) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    if (!SetupCardDetectIST(pHardwareContext))
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
    }

exitInit:

    if (!SD_API_SUCCESS(status)) {
            // just call the deinit handler directly to cleanup
        SDDeinitialize(pHCContext);
    }

    return status;

}

///////////////////////////////////////////////////////////////////////////////
//  SDHCancelIoHandler - io cancel handler 
//  Input:  pHostContext - host controller context
//          Slot - slot the request is going on
//          pRequest - the request to be cancelled
//          
//  Output: 
//  Return: TRUE if the request was cancelled
//  Notes:  
//          
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN SDHCancelIoHandler(PSDCARD_HC_CONTEXT pHCContext, 
                             DWORD              Slot, 
                             PSD_BUS_REQUEST    pRequest)
{
    PSDH_HARDWARE_CONTEXT    pController;

        // for now, we should never get here because all requests are non-cancelable
        // the hardware supports timeouts so it is impossible for the controller to get stuck
    DEBUG_ASSERT(FALSE);

        // get our extension 
    pController = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

        // --- Stop hardware, cancel the request!

        // release the lock before we complete the request
    SDHCDReleaseHCLock(pHCContext);
 
        // complete the request with a cancelled status
    SDHCDIndicateBusRequestComplete(pHCContext,
                                    pRequest,
                                    SD_API_STATUS_CANCELED);

    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
//  SDHBusRequestHandler - bus request handler 
//  Input:  pHostContext - host controller context
//          Slot - slot the request is going on
//          pRequest - the request
//          
//  Output: 
//  Return: SD_API_STATUS Code
//  Notes:  The request passed in is marked as uncancelable, this function
//          has the option of making the outstanding request cancelable    
//          
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDHBusRequestHandler(PSDCARD_HC_CONTEXT pHCContext, 
                                     DWORD              Slot, 
                                     PSD_BUS_REQUEST    pRequest) 
{
    BOOL fExtraDelay = FALSE;
    PSDH_HARDWARE_CONTEXT    pController;     // our controller
    DWORD                      cmdatRegister;   // CMDAT register

    DbgPrintZo(SDCARD_ZONE_FUNC, (TEXT("SDHBusRequestHandler - CMD: 0x%02X DATA: 0x%08X, TC: %d\n"),
                pRequest->CommandCode, pRequest->CommandArgument, pRequest->TransferClass));

        // get our extension 
    pController = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

    DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("SDHBusRequestHandler - CMD: 0x%02X DATA: 0x%08X, TC: %d\n"),
            pRequest->CommandCode, pRequest->CommandArgument, pRequest->TransferClass));

        // stop the clock
    SDClockOff(pController);

        // set the command
    pController->pSDMMCRegisters->CMD = pRequest->CommandCode;
        // set the argument,  high part
    pController->pSDMMCRegisters->ARGH = (pRequest->CommandArgument >> 16);
        // set the argument,  high part
    pController->pSDMMCRegisters->ARGL = (pRequest->CommandArgument & 0x0000FFFF);


    switch (pRequest->CommandResponse.ResponseType) {

        case NoResponse:
            cmdatRegister = MMC_CMDAT_RESPONSE_NONE;
            break;
        case ResponseR1b:
                // response1 with busy signalling
            cmdatRegister = MMC_CMDAT_RESPONSE_R1 | MMC_CMDAT_EXPECT_BUSY;
            break;
        case ResponseR1:
        case ResponseR5:
        case ResponseR6:
                // on an MMC controller R5 and R6 are really just an R1 response (CRC protected)
            cmdatRegister = MMC_CMDAT_RESPONSE_R1;
            break;
        case ResponseR2:    
            cmdatRegister = MMC_CMDAT_RESPONSE_R2;
            break;
        case ResponseR3:
        case ResponseR4:    
                // R4 is really same as an R3 response on an MMC controller (non-CRC)
            cmdatRegister = MMC_CMDAT_RESPONSE_R3;
            break;

        default:
            DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("SDHBusRequestHandler failed (Invalid parameter)\n")));
            return SD_API_STATUS_INVALID_PARAMETER;
    }

        // check for Command Only
    if ((SD_COMMAND == pRequest->TransferClass)) {
       
            // set the length of the block
        pController->pSDMMCRegisters->BLKLE = 0;

            // set the number of blocks
        pController->pSDMMCRegisters->NOB = 0;

    } else {
            // its a command with a data phase
        cmdatRegister |= MMC_CMDAT_DATA_EN;
        
            // set the buffer index to the end of the buffer
        pRequest->HCParam = 0;      

            // set the length of the block
        pController->pSDMMCRegisters->BLKLE = pRequest->BlockSize;

            // set the number of blocks
        pController->pSDMMCRegisters->NOB = pRequest->NumBlocks;

            // check for write
        if (TRANSFER_IS_WRITE(pRequest)) {
            cmdatRegister |= MMC_CMDAT_DATA_WRITE;
        } 

        
    }

        // check to see if we need to append the 80 clocks (i.e. this is the first transaction)
    if (pController->SendInitClocks) {
        pController->SendInitClocks = FALSE;
        cmdatRegister |= MMC_CMDAT_INIT;

    }

        // write the CMDAT register
    pController->pSDMMCRegisters->CMDAT = cmdatRegister;
    DbgPrintZo(SDH_SEND_ZONE, (TEXT("SDHBusRequestHandler - CMDAT Reg: 0x%08X, CMD:%d \n"),
                cmdatRegister, pRequest->CommandCode));

        // set the the response timeout
    pController->pSDMMCRegisters->RESTO = SDH_DEFAULT_RESPONSE_TIMEOUT_CLOCKS;
        // set the data receive timeout
    pController->pSDMMCRegisters->RDTO = SDH_DEFAULT_DATA_TIMEOUT_CLOCKS;

    SetCurrentState(pController, CommandSend);
        // turn on just the command complete interrupt
    END_CMD_INTERRUPT_ON(pController);

        // turn on the clock 
    SDClockOn(pController);
       
#if DEBUG
    {
        DWORD mmcStatus;

        mmcStatus = pController->pSDMMCRegisters->STAT;

        if (mmcStatus & 0x0000003F) {
                // these errors should be cleared
            DbgPrintZo(SDCARD_ZONE_ERROR, 
                (TEXT("********* SDHBusRequestHandler - MMC Status did not clear : 0x%08X \n"),
                (mmcStatus & 0x0000003F)));
        }
    
    }
#endif 
    DbgPrintZo(SDH_SEND_ZONE, (TEXT("SDHBusRequestHandler - Request Sent\n")));

    return SD_API_STATUS_PENDING;
}

///////////////////////////////////////////////////////////////////////////////
//  SDHSlotOptionHandler - handler for slot option changes
//  Input:  pHostContext - host controller context
//          SlotNumber   - the slot the change is being applied to
//          Option       - the option code
//          pData        - data associated with the option
//          OptionSize   - size of option data
//  Output: 
//  Return: SD_API_STATUS code
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDHSlotOptionHandler(PSDCARD_HC_CONTEXT    pHCContext,
                                     DWORD                 SlotNumber, 
                                     SD_SLOT_OPTION_CODE   Option, 
                                     PVOID                 pData,
                                     ULONG                 OptionSize)
{
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;   // status
    PSDH_HARDWARE_CONTEXT    pController;         // the controller
    PSD_HOST_BLOCK_CAPABILITY  pBlockCaps;          // queried block capabilities

        // get our extension 
    pController = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

    switch (Option) {

        case SDHCDSetSlotPower:
            DbgPrintZo(SDCARD_ZONE_INIT, 
                (TEXT("SDHSlotOptionHandler - called - SetSlotPower : 0x%08X  \n"), 
                *((PDWORD)pData)));
            break;

        case SDHCDSetSlotInterface:
            DbgPrintZo(SDCARD_ZONE_INIT, 
                (TEXT("SDHSlotOptionHandler - called - SetSlotInterface : Clock Setting: %d \n"), 
                ((PSD_CARD_INTERFACE)pData)->ClockRate));
            
            if (SD_INTERFACE_SD_MMC_1BIT == 
                ((PSD_CARD_INTERFACE)pData)->InterfaceMode) {
                DbgPrintZo(SDCARD_ZONE_INIT, 
                        (TEXT("SDHSlotOptionHandler - called - SetSlotInterface : setting for 1 bit mode \n")));

⌨️ 快捷键说明

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