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

📄 sdcardio.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 CPP
📖 第 1 页 / 共 4 页
字号:

    // get a copy
    regValue = pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIntEnable;

    // check to see if there are interrupts to keep enabled
    if (!(regValue & SD_IO_INT_ENABLE_ALL_FUNCTIONS)) {
        // if none, then clear out master enable
        regValue &= ~SD_IO_INT_ENABLE_MASTER_ENABLE;
        pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIntEnable = regValue;
    }

    // set status
    status = SD_API_STATUS_SUCCESS; 

    // now check and see if we need to enable/disable interrupts in the host controller
    if (Connect) {
        // check to see if the interrupt logic is already on
        if (!IS_SLOT_SDIO_INTERRUPT_ON(pDevice->pSlot)) {
            // enable it in the host controller
            status = SDEnableSDIOInterrupts(pDevice->pSlot);

            if (SD_API_SUCCESS(status)) {
                // flag it as on
                FLAG_SD_SLOT_INTERRUPTS_ON(pDevice->pSlot);
            }
        }

    } else {
        // check to see if all the interrupts have been turned off
        if (0 == regValue) {
            // disable interrupts, we don't really care about the result
            SDDisableSDIOInterrupts(pDevice->pSlot);
            // flag it off
            FLAG_SD_SLOT_INTERRUPTS_OFF(pDevice->pSlot);
        } 
    }

    if (!SD_API_SUCCESS(status)) {
        SDDCReleaseDeviceLock(pParentDevice);
        return status;
    }

    // update the INT Enable register
    status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
        SD_IO_WRITE,          
        0,      // all from function 0
        SD_IO_REG_INT_ENABLE,
        FALSE,
        &regValue,   // reg
        1);           

    if (!SD_API_SUCCESS(status)) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDIOConnectDisconnectInterrupt: failed to write INT_ENABLE register for function %d \n"),
            pDevice->SDCardInfo.SDIOInformation.Function));                
        pDevice->SDCardInfo.SDIOInformation.pInterruptCallBack = NULL;
    } else {
        if (Connect) {
            DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDIOConnectDisconnectInterrupt: Interrupt enabled for function %d \n"),
                pDevice->SDCardInfo.SDIOInformation.Function));
        } else {
            DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDIOConnectDisconnectInterrupt: Interrupt disabled for function %d \n"),
                pDevice->SDCardInfo.SDIOInformation.Function)); 
        }
    }

    SDDCReleaseDeviceLock(pParentDevice);

    return status;

}

///////////////////////////////////////////////////////////////////////////////
//  SDIOConnectInterrupt  - Associate an interrupt service routine for an SDIO
//                          peripheral interrupt
//  Input:  hDevice   - SD device handle
//          pIsrFunction - the interrupt service routine
//  Output: 
//  Return: SD_API_STATUS code
//          
//  Notes: This function is provided for an SDIO peripheral driver to 
//         register an interrupt routine for the device. 
//         The interrupt function has the form of PSD_INTERRUPT_CALLBACK.
//         The caller should call SDIODisconnectInterrupt when cleaning up
//         the device. The bus driver will enable the interrupt for the function in the
//         card's CCCR area prior to returning from this function. 
//         The interrupt callback is called whenever the device function is 
//         interrupting. The bus driver will determine the interrupting function,
//         disable the interrupt on the card and call the callback.  Upon return 
//         from the callback the bus driver will reenable the interrupt in the
//         card's CCR.
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDIOConnectInterrupt__X(SD_DEVICE_HANDLE         hDevice, 
                                      PSD_INTERRUPT_CALLBACK   pIsrFunction)
{
    // All error checking is done in SDIOConnectDisconnectInterrupt.
    return SDIOConnectDisconnectInterrupt(hDevice, 
        pIsrFunction,
        TRUE);
}

///////////////////////////////////////////////////////////////////////////////
//  SDIODisconnectInterrupt  - disconnect the interrupt 
//  Input:  hDevice   - SD device handle
//  Output: 
//  Return: 
//          
//  Notes: This function should be called to disconnect the interrupt
//         from the device. The bus driver will disable the interrupt in the
//         card's CCCR area
///////////////////////////////////////////////////////////////////////////////
VOID SDIODisconnectInterrupt__X(SD_DEVICE_HANDLE hDevice)
{
    // All error checking is done in SDIOConnectDisconnectInterrupt.
    SDIOConnectDisconnectInterrupt(hDevice, 
        NULL,
        FALSE);
}


///////////////////////////////////////////////////////////////////////////////
//  SDSetFunctionBlockSize  - set the block size of the function
//  Input:  pDevice   - the device 
//          BlockSize - block size to set
//  Output: 
//  Return: SD_API_STATUS code
//          
//  Notes: 
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDSetFunctionBlockSize(PSDCARD_DEVICE_CONTEXT pDevice,
                                     DWORD                  BlockSize)
{
    USHORT bytesPerBlock = (USHORT)BlockSize; // desired block size
    DWORD                  FBROffset;         // FBR offset
    SD_API_STATUS          status;

    DEBUGCHK(0 != pDevice->SDCardInfo.SDIOInformation.Function);

    // calculate the FBR offset based on the function number
    FBROffset = SD_IO_FBR_1_OFFSET + (pDevice->SDCardInfo.SDIOInformation.Function - 1) *
        SD_IO_FBR_LENGTH;

    // update the register
    status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
        SD_IO_WRITE,          
        0,      // all from function 0
        FBROffset + SD_IO_FBR_IO_BLOCK_SIZE,
        FALSE,
        (PUCHAR)&bytesPerBlock,   // reg
        sizeof(USHORT));           // two bytes    


    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  SDEnableFunction  - enable/disable the device function 
//  Input:  pDevice   - the device 
//          pInfo   - enable info (required if Enable is TRUE)
//          Enable  - enable
//  Output: 
//  Return: SD_API_STATUS code
//          
//  Notes: 
///////////////////////////////////////////////////////////////////////////////
static
SD_API_STATUS SDEnableDisableFunction(PSDCARD_DEVICE_CONTEXT      pDevice,
                                      PSD_IO_FUNCTION_ENABLE_INFO pInfo,
                                      BOOL                        Enable)
{
    PREFAST_DEBUGCHK(pDevice);

    PSDCARD_DEVICE_CONTEXT      pParentDevice;  // parent device
    UCHAR                       regValue;       // temp register value
    ULONG                       retryCount;     // ready retry count
    SD_API_STATUS               status;         // intermediate status
	BOOL                        fSkipIfMatch;   // Test for setting the same bit twice
    FUNCTION_POWER_STATE        PowerState;     // The function's power state
    PSD_CHANGE_CARD_POWER       pPowerChangeHandler; 
    CSDBusDriver                *pBusDriver;    // Pointer to the bus driver class


        // get the parent device
    pParentDevice = pDevice->pParentDevice;

    if (NULL == pParentDevice) {
        DEBUGCHK(FALSE);
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDEnableDisableFunction: Enabling/Disabling SDIO Device Function %d \n"),
        pDevice->SDCardInfo.SDIOInformation.Function));
		
	    // Get a pointer to the bus driver calss
	pBusDriver = SDDCGetBusDriver(pDevice);

        // Get the functions power state
    status = pBusDriver->GetFunctionPowerState(pDevice, &PowerState);

    if (!SD_API_SUCCESS(status)) {
        return status;
    }

		// First check if states already match
    fSkipIfMatch = FALSE;
    if (PowerState.fFunctionEnabled == Enable)
    {
        if (Enable) { 
            DEBUGMSG(SDCARD_ZONE_WARN, 
                    (TEXT("SDEnableDisableFunction: Attempting to enable function that is already enabled \n")));
            fSkipIfMatch = TRUE;
        }
        else
        {
            DEBUGMSG(SDCARD_ZONE_WARN, 
                    (TEXT("SDEnableDisableFunction: Attempting to disable function that is already disabled \n")));
            fSkipIfMatch = TRUE;
        }
    }
        
    if (!fSkipIfMatch) {

            // Attempt to change cards power draw
        pPowerChangeHandler = SDHCDGetChangePowerHandler(pDevice->pSlot->pHostController);
        status = pPowerChangeHandler(pDevice->pSlot->pHostController, pDevice->pSlot->SlotIndex, PowerState.EnableDelta);

        if (!SD_API_SUCCESS(status)) {
            return status;
        }

            //update the power used at the slot
        {
            INT SlotPower = (INT)SDHCDGetSlotPower(pDevice->pSlot->pHostController, pDevice->pSlot->SlotIndex);

            SlotPower += PowerState.EnableDelta;

            if(SlotPower >= 0)
            {
                SDHCDSetSlotPower(pDevice->pSlot->pHostController, pDevice->pSlot->SlotIndex, (USHORT)SlotPower);
            }
            else
            {
                SDHCDSetSlotPower(pDevice->pSlot->pHostController, pDevice->pSlot->SlotIndex, 0);
            }
        }

            // must interlock this request with the parent device to update the shadow register
        SDDCAcquireDeviceLock(pParentDevice);

            // update the parent device shadow register
        if (Enable) {     
            pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIOEnable 
                |= (1 <<  pDevice->SDCardInfo.SDIOInformation.Function);
        } else {
            pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIOEnable &= 
                ~(1 <<  pDevice->SDCardInfo.SDIOInformation.Function);
        }
            // get a copy
        regValue = pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIOEnable;

            // release the parent lock
        SDDCReleaseDeviceLock(pParentDevice);
            // update the register
        status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
        SD_IO_WRITE,          
        0,      // all from function 0
        SD_IO_REG_ENABLE,
        FALSE,
        &regValue,   // reg
        1);         // one byte
        
        if (!SD_API_SUCCESS(status)) {
            return status;
        }
    }

    // if enabling we check for I/O ready
    if (Enable) { 
        retryCount = pInfo->ReadyRetryCount;

        while (retryCount) {
            // delay the interval time
            Sleep(pInfo->Interval);

            // read the I/O ready register
            status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
                SD_IO_READ,          
                0,      // all from function 0
                SD_IO_REG_IO_READY,

⌨️ 快捷键说明

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