📄 sdcontrol.cpp
字号:
// If the transfer could not be supported by DMA
if (pController->fDMATransfer == FALSE)
{
// Unlock the pages we previously locked to build the scatter-gather list
UnlockPages(pBuffer, dwNumBytesToTransfer);
}
else
{
// Save size of the scatter-gather list we built
pController->DmaChainSize = currentDesc;
#ifdef SDHC_SDMA_VERBOSE
RETAILMSG(TRUE, (_T("Chain size: %d, stranded bytes %d, FIFO size = %d, transfer size = %d\r\n"), pController->DmaChainSize, pController->DmaStrandedBytes, pController->Bytes_in_fifo, dwNumBytesToTransfer));
#endif
}
}
}
// check to see if we need to append the 80 clocks (i.e. this is the first transaction)
if (pController->SendInitClocks)
{
pController->SendInitClocks = FALSE;
CSP_BITFINS(cmdatRegister, SDHC_CDC_INIT, 1);
}
// check to see if we need to enable wide bus (4 bit) data transfer mode
CSP_BITFINS(cmdatRegister, SDHC_CDC_BW, pController->BusWidthSetting);
DEBUGMSG(ZONE_INFO, (TEXT("SDHBusRequestHandler - CMDAT: 0x%08X, CMD:%d ARG:0x%08X, TxClass: %d\r\n"),
cmdatRegister, pRequest->CommandCode, pRequest->CommandArgument, pRequest->TransferClass));
// Check if clock gating between commands is supported
if (pController->fClockGatingSupported == TRUE)
{
// Controller clocks needs to be enabled
BSPSdhcSetClockGatingMode(TRUE, pController->ControllerIndex);
// update this variable after enabling the clocks to
// avoid possible race conditions
pController->fClockGatedOff = FALSE; // controller clocks are enabled
}
// clear all status
OUTREG32(&pController->pSDMMCRegisters->STATUS, 0xFFFFFFFF);
// Enable End Command Response interrupt
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_ECR, 1);
// set the command
INSREG32BF(&pController->pSDMMCRegisters->CMD, SDHC_CMD_CMD, pRequest->CommandCode);
// set the argument
INSREG32BF(&pController->pSDMMCRegisters->ARG, SDHC_ARG_ARG, pRequest->CommandArgument);
switch (pRequest->TransferClass)
{
case SD_COMMAND:
// No data associated with this command
INSREG32BF(&pController->pSDMMCRegisters->BLK_LEN, SDHC_BL_BL, 0);
INSREG32BF(&pController->pSDMMCRegisters->NOB, SDHC_NOB_NOB, 0);
break;
case SD_WRITE:
// Enable Write Operation Done interrupt
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_WODONE, 1);
// Set transfer length
INSREG32BF(&pController->pSDMMCRegisters->BLK_LEN, SDHC_BL_BL, pRequest->BlockSize);
// Set Number of Blocks
INSREG32BF(&pController->pSDMMCRegisters->NOB, SDHC_NOB_NOB, pRequest->NumBlocks);
break;
case SD_READ:
// Clear the read operation done flag
pController->fDmaRdOpDone = FALSE;
// Enable Read Operation Done interrupt
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_RODONE, 1);
//Specify the Read Time Out value
INSREG32BF(&pController->pSDMMCRegisters->READ_TO, SDHC_READTO_TO, pController->ulReadTimeout);
// Set transfer length
INSREG32BF(&pController->pSDMMCRegisters->BLK_LEN, SDHC_BL_BL, pRequest->BlockSize);
// Set Number of Blocks
INSREG32BF(&pController->pSDMMCRegisters->NOB, SDHC_NOB_NOB, pRequest->NumBlocks);
break;
}
// write the CMDAT register
OUTREG32(&pController->pSDMMCRegisters->CMD_DAT_CONT, cmdatRegister);
//start clock
SetClock(pController, TRUE);
DEBUGMSG(ZONE_FUNCTION, (TEXT("- SDHBusRequestHandler - Request Sent\r\n")));
return SD_API_STATUS_PENDING;
}
//------------------------------------------------------------------------------
//
// Function: SDHSlotOptionHandler
//
// handler for slot option changes
//
// Parameters:
// pHostContext[in] - host controller context
// SlotNumber[in] - the slot the change is being applied to
// Option[in] - the option code
// pData[in] - data associated with the option
// OptionSize[in] - size of option data
//
// Returns:
// SD_API_STATUS Code
//
//------------------------------------------------------------------------------
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 SDHCDAckSDIOInterrupt:
case SDHCDEnableSDIOInterrupts:
if (!pData && OptionSize == 0)
{
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler - called - Ack/EnableSDIOInterrupts : on slot %d\r\n"),
SlotNumber));
// Check if clock gating between commands is supported
if (pController->fClockGatingSupported == TRUE)
{
BSPSdhcSetClockGatingMode(TRUE, pController->ControllerIndex);
// Enable SDIO Wakeup interrupt before cutting off the controller clock
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_SDIOIRQWKP, 1);
//Enable SDIO interrupt
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_SDIOIRQ, 1);
// update this variable before disabling the clocks to
// avoid possible race conditions
pController->fClockGatedOff = TRUE; // controller clocks are disabled
BSPSdhcSetClockGatingMode(FALSE, pController->ControllerIndex);
}
else
{
//Enable SDIO interrupt
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_SDIOIRQ, 1);
}
pController->fSDIOEnabled = TRUE;
} else
status = SD_API_STATUS_INVALID_PARAMETER;
break;
case SDHCDDisableSDIOInterrupts:
if (!pData && OptionSize == 0)
{
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler - called - DisableSDIOInterrupts : on slot %d \r\n"),
SlotNumber));
// Check if clock gating between commands is supported
if (pController->fClockGatingSupported == TRUE)
{
BSPSdhcSetClockGatingMode(TRUE, pController->ControllerIndex);
// Disable SDIO interrupt
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_SDIOIRQ, 0);
pController->fClockGatedOff = TRUE; // controller clocks are disabled
BSPSdhcSetClockGatingMode(FALSE, pController->ControllerIndex);
}
else
{
// Disable SDIO interrupt
INSREG32BF(&pController->pSDMMCRegisters->INT_CNTR, SDHC_INT_SDIOIRQ, 0);
}
pController->fSDIOEnabled = FALSE;
} else
status = SD_API_STATUS_INVALID_PARAMETER;
break;
case SDHCDSetSlotInterface:
if (pData && OptionSize == sizeof(SD_CARD_INTERFACE))
{
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler - called - SetSlotInterface : Clock Setting: %d \r\n"),
((PSD_CARD_INTERFACE)pData)->ClockRate));
if (SD_INTERFACE_SD_MMC_1BIT ==
((PSD_CARD_INTERFACE)pData)->InterfaceMode)
{
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler - called - SetSlotInterface : setting for 1 bit mode \r\n")));
pController->f4BitMode = FALSE;
pController->BusWidthSetting = 0;
pController->Units_in_fifo = 4;
if (pController->Bytes_in_fifo != 16)
{
pController->Bytes_in_fifo = 16 ; //16bytes
pController->fDmaUpdateContext = TRUE;
}
} else if (SD_INTERFACE_SD_4BIT == ((PSD_CARD_INTERFACE)pData)->InterfaceMode)
{
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler - called - SetSlotInterface : setting for 4 bit mode \r\n")));
pController->f4BitMode = TRUE;
pController->BusWidthSetting = 2;
pController->Units_in_fifo = 4*4;
if (pController->Bytes_in_fifo != 64)
{
pController->Bytes_in_fifo = 64; //64 bytes
pController->fDmaUpdateContext = TRUE;
}
}
// Check if clock gating between commands is supported
if (pController->fClockGatingSupported == TRUE)
{
// Controller clocks needs to be enabled
BSPSdhcSetClockGatingMode(TRUE, pController->ControllerIndex);
// set rate
SetClock(pController, FALSE);
SetRate(pController, &((PSD_CARD_INTERFACE)pData)->ClockRate, TRUE);
pController->fClockGatedOff = TRUE; // controller clocks are disabled
// disable controller clocks
BSPSdhcSetClockGatingMode(FALSE, pController->ControllerIndex);
}
else
{
// set rate
SetClock(pController, FALSE);
SetRate(pController, &((PSD_CARD_INTERFACE)pData)->ClockRate, TRUE);
}
if (!SD_API_SUCCESS(status))
{
ERRORMSG(ZONE_ERROR, (TEXT("SDHSlotOptionHandler: Failed to set Card Interface\n")));
}
} else
status = SD_API_STATUS_INVALID_PARAMETER;
break;
case SDHCDSetSlotPower:
if (pData && OptionSize == sizeof(DWORD))
{
//takes a DWORD for the power bit mask
UINT32 dwVddSettingMask = *(UINT32 *)pData;
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler - called - SDHCDSetSlotPower : 0x%X \r\n"),
dwVddSettingMask));
//Copy Slot Vdd voltage to hardware context. This will be used to set slot power
//during wakeup
pController->dwVddSettingMask = dwVddSettingMask ;
// Vary voltage setting based on request.
BSPSetVoltageSlot(pController->ControllerIndex, dwVddSettingMask) ;
} else
status = SD_API_STATUS_INVALID_PARAMETER;
break;
case SDHCDSetSlotPowerState:
if (pData && OptionSize == sizeof(CEDEVICE_POWER_STATE))
{
CEDEVICE_POWER_STATE ps = *(CEDEVICE_POWER_STATE *)pData;
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler - called - SDHCDSetSlotPowerState : %d \r\n"),
ps));
SetHardwarePowerState(pController, ps);
} else
status = SD_API_STATUS_INVALID_PARAMETER;
break;
case SDHCDGetSlotPowerState:
if (pData && OptionSize == sizeof(CEDEVICE_POWER_STATE))
{
*(CEDEVICE_POWER_STATE *)pData = pController->CurrentPowerState;
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler - called - GetSlotPower : %d \r\n"),
*((CEDEVICE_POWER_STATE *)pData)));
} else
status = SD_API_STATUS_INVALID_PARAMETER;
break;
case SDHCDWakeOnSDIOInterrupts:
if (pData && OptionSize == sizeof(BOOL))
{
// TODO: Enable wake on SDIO int
BOOL fEnable = *(BOOL *)pData;
if (fEnable)
{
//Indicate that SDIO wake up is supported
pController->fWakeOnSDIOInt = TRUE;
} else
{
//Indicate that SDIO wake up is not supported
pController->fWakeOnSDIOInt = FALSE;
}
} else
status = SD_API_STATUS_INVALID_PARAMETER;
break;
case SDHCDGetWriteProtectStatus:
if (pData && OptionSize == sizeof(SD_CARD_INTERFACE))
{
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler - called - SDHCDGetWriteProtectStatus : on slot %d \r\n"),
SlotNumber));
if ( BSPSdhcIsCardWriteProtected(pController->ControllerIndex) )
{
((PSD_CARD_INTERFACE)pData)->WriteProtected = TRUE;
DEBUGMSG(ZONE_INFO, (TEXT("SDHSlotOptionHandler - Card is write protected \r\n")));
} else
{
((PSD_CARD_INTERFACE)pData)->WriteProtected = FALSE;
DEBUGMSG(ZONE_INFO, (TEXT("SDHSlotOptionHandler - Card is write enabled \r\n")));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -