?? sdio.c
字號:
}
#endif //#ifdef USE_DMA
// turn on the clock
// SDIOClockOn(pSlot);
SD_INTERRUPTS_CLEAR(pSlot,SD_Int_CRC_Errors |
SD_Int_Response_Timeout |
SD_Int_Response_Done );
// enable response done and response timeout interrupts
SD_INTERRUPTS_ENABLE(pSlot, SD_Int_Response_Done | SD_Int_Response_Timeout );
// for Stop Transmission and IO Abort disable clock freezing to
// get the state machine running again to send command
if ((SD_CMD_STOP_TRANSMISSION == pRequest->CommandCode) ||
(SD_CMD_IO_RW_DIRECT == pRequest->CommandCode && SD_IO_REG_IO_ABORT == IO_RW_DIRECT_ADDR_ARG(pRequest->CommandArgument))) {
tmp = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->config2);
tmp |= SD_CONFIG2_DF;
WRITE_REGISTER_ULONG((PULONG)&pSlot->pSD->config2, tmp);
}
// remember whether the last command is CMD53 or not.
lastCmd53 = ( SD_CMD_IO_RW_EXTENDED == pRequest->CommandCode );
// write the 32 bit command argument
WRITE_REGISTER_ULONG((PULONG)&pSlot->pSD->cmdarg, pRequest->CommandArgument );
// write the completed command register - this will issue the command
WRITE_REGISTER_ULONG((PULONG)&pSlot->pSD->cmd, commandRegister );
DEBUGMSG(SDIO_SEND_ZONE,(TEXT("Send Command - CMD register = 0x%08X\r\n"),commandRegister));
return SD_API_STATUS_PENDING;
}
///////////////////////////////////////////////////////////////////////////////
// SDIOSDCancelIoHandler - 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 request cancelled
// Notes: the HC lock is taken before entering this cancel handler
///////////////////////////////////////////////////////////////////////////////
BOOLEAN SDIOCancelIoHandler(PSDCARD_HC_CONTEXT pHCContext, DWORD Slot, PSD_BUS_REQUEST pRequest)
{
PSDIO_HW_CONTEXT pController; // the controller
// 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(PSDIO_HW_CONTEXT, pHCContext);
// TODO --- 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;
}
///////////////////////////////////////////////////////////////////////////////
// SDIOSlotOptionHandler - handler for slot option changes
// Input: pHostContext - host controller context
// Slot - 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
// Notes:
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDIOSlotOptionHandler(PSDCARD_HC_CONTEXT pHCContext,
DWORD Slot,
SD_SLOT_OPTION_CODE Option,
PVOID pData,
ULONG OptionSize)
{
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // status
PSDIO_HW_CONTEXT pController; // the controller
PSD_HOST_BLOCK_CAPABILITY pBlockCaps; // queried block capabilities
ULONG tmp;
// get our extension
pController = GetExtensionFromHCDContext(PSDIO_HW_CONTEXT, pHCContext);
switch (Option) {
case SDHCDSetSlotPower:
// can't set power so ignore this
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SetSlotPower : 0x%08X \n"), *((PDWORD)pData)));
break;
case SDHCDSetSlotInterface:
// shut off clock first
SDIOClockOff(&pController->Slots[Slot]);
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SetSlotInterface : Clock Setting: %d \n"),
((PSD_CARD_INTERFACE)pData)->ClockRate));
if (SD_INTERFACE_SD_MMC_1BIT == ((PSD_CARD_INTERFACE)pData)->InterfaceMode) {
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SetSlotInterface : setting for 1 bit mode \n")));
tmp = READ_REGISTER_ULONG((PULONG)&pController->Slots[Slot].pSD->config2);
tmp &= ~SD_CONFIG2_WB;
WRITE_REGISTER_ULONG((PULONG)&pController->Slots[Slot].pSD->config2,tmp);
} else if (SD_INTERFACE_SD_4BIT == ((PSD_CARD_INTERFACE)pData)->InterfaceMode) {
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SetSlotInterface : setting for 4 bit mode \n")));
tmp = READ_REGISTER_ULONG((PULONG)&pController->Slots[Slot].pSD->config2);
tmp |= SD_CONFIG2_WB;
WRITE_REGISTER_ULONG((PULONG)&pController->Slots[Slot].pSD->config2,tmp);
} else {
DEBUG_ASSERT(FALSE);
}
// set rate
SDIOSetRate(&pController->Slots[Slot], &((PSD_CARD_INTERFACE)pData)->ClockRate);
break;
case SDHCDEnableSDIOInterrupts:
// enable SDIO interrupt detection
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - EnableSDIOInterrupts : on slot %d \n"),Slot));
SD_INTERRUPTS_ENABLE(&pController->Slots[Slot],SD_Int_SDIO_Interrupt);
break;
case SDHCDAckSDIOInterrupt:
// re-enable SDIO interrupt detection
SD_INTERRUPTS_ENABLE(&pController->Slots[Slot],SD_Int_SDIO_Interrupt);
break;
case SDHCDDisableSDIOInterrupts:
// disable SDIO interrupt detection
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - DisableSDIOInterrupts : on slot %d \n"),Slot));
SD_INTERRUPTS_DISABLE(&pController->Slots[Slot],SD_Int_SDIO_Interrupt);
break;
case SDHCDGetWriteProtectStatus:
// get the write protect status
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SDHCDGetWriteProtectStatus : on slot %d \n"),Slot));
if (SDIOPlatCardWriteProteced(pController,Slot)) {
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - Card is Write Protected\n")));
((PSD_CARD_INTERFACE)pData)->WriteProtected = TRUE;
} else {
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - Card is NOT Write Protected\n")));
((PSD_CARD_INTERFACE)pData)->WriteProtected = FALSE;
}
break;
case SDHCDQueryBlockCapability:
// set the block capability
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SDHCDQueryBlockCapability : on slot %d \n"),Slot));
pBlockCaps = (PSD_HOST_BLOCK_CAPABILITY)pData;
DEBUGMSG(SDCARD_ZONE_INIT,
(TEXT("SDIOSDSlotOptionHandler: Read Block Length: %d , Read Blocks: %d\n"),
pBlockCaps->ReadBlockSize,
pBlockCaps->ReadBlocks));
DEBUGMSG(SDCARD_ZONE_INIT,
(TEXT("SDIOSDSlotOptionHandler: Write Block Length: %d , Write Blocks: %d\n"),
pBlockCaps->WriteBlockSize,
pBlockCaps->WriteBlocks));
// the Au1100 SD controller can only handle up to 2048 bytes for each block.
if (pBlockCaps->ReadBlockSize > SD_MAX_BLOCK_SIZE) {
RETAILMSG(1,
(TEXT("SDIOSDSlotOptionHandler: Read Block Length: %d is out of the range!\n"),
pBlockCaps->ReadBlockSize));
pBlockCaps->ReadBlockSize = SD_MAX_BLOCK_SIZE;
}
if (pBlockCaps->WriteBlockSize > SD_MAX_BLOCK_SIZE) {
RETAILMSG(1,
(TEXT("SDIOSDSlotOptionHandler: Write Block Length: %d is out of the range!\n"),
pBlockCaps->WriteBlockSize));
pBlockCaps->WriteBlockSize = SD_MAX_BLOCK_SIZE;
}
// the Au1100 SD controller can only handle up to 511 blocks per transfer
if (pBlockCaps->ReadBlocks > SD_MAX_BLOCK_COUNT ) {
RETAILMSG(1,
(TEXT("SDIOSDSlotOptionHandler: Read Block count: %d is out of the range!\n"),
pBlockCaps->ReadBlocks));
pBlockCaps->ReadBlocks = SD_MAX_BLOCK_COUNT;
}
if (pBlockCaps->WriteBlocks > SD_MAX_BLOCK_COUNT ) {
RETAILMSG(1,
(TEXT("SDIOSDSlotOptionHandler: Write Block count: %d is out of the range!\n"),
pBlockCaps->WriteBlocks));
pBlockCaps->WriteBlocks = SD_MAX_BLOCK_COUNT;
}
break;
case SDHCDGetSlotInfo:
{
PSDCARD_HC_SLOT_INFO pSlotInfo = pData;
// set the slot capabilities
SDHCDSetSlotCapabilities(pSlotInfo, SD_SLOT_SD_4BIT_CAPABLE |
SD_SLOT_SD_1BIT_CAPABLE |
SD_SLOT_SDIO_CAPABLE |
SD_SLOT_SDIO_INT_DETECT_4BIT_MULTI_BLOCK);
// set voltage window mask +- 10%
SDHCDSetVoltageWindowMask(pSlotInfo, ( SD_VDD_WINDOW_3_1_TO_3_2 | SD_VDD_WINDOW_3_2_TO_3_3 | SD_VDD_WINDOW_3_3_TO_3_4));
// set optimal voltage
SDHCDSetDesiredSlotVoltage(pSlotInfo, SD_VDD_WINDOW_3_2_TO_3_3 );
// set max clock rate
SDHCDSetMaxClockRate(pSlotInfo, 25000000);
// set power up delay
SDHCDSetPowerUpDelay(pSlotInfo, 200 );
}
break;
default:
status = SD_API_STATUS_INVALID_PARAMETER;
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// RemoveDevice - remove the device in the slot
// Input: pSlot - slot context
// Output:
// Return:
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID RemoveDevice(PSDIO_SLOT pSlot)
{
PSD_BUS_REQUEST pRequest; // request to cancel
// indicate the slot change
SDHCDIndicateSlotStateChange(pSlot->pController->pHCContext,
pSlot->SlotNumber,
DeviceEjected);
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("RemoveDevice: Card Removal Detected - \n")));
// get the current request
pRequest = pSlot->pCurrentRequest;
#ifdef DEBUG
DumpSlot(pSlot);
#endif
if (pRequest != NULL) {
CompleteRequest(pSlot, SD_API_STATUS_DEVICE_REMOVED);
}
ResetSlot(pSlot, FALSE);
}
///////////////////////////////////////////////////////////////////////////////
// HandleTransferErrors - Check for and handle transfer error conditions
// Input: pSlot - slot context
// pRequest - the request
// Output:
// Return: TRUE if an error condition occurred and the request got completed
// Notes: If an error is detected the request will be completed.
///////////////////////////////////////////////////////////////////////////////
BOOL HandleTransferErrors(PSDIO_SLOT pSlot,
PSD_BUS_REQUEST pRequest,
ULONG CRCMask)
{
ULONG status;
status = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->status);
SD_INTERRUPTS_CLEAR(pSlot,CRCMask|SD_Int_Data_Timeout|SD_Int_Response_Timeout);
if (status & CRCMask) {
ResetSlot(pSlot, FALSE);
DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: CRC Error %08X\r\n"),pSlot->SlotNumber,status));
CompleteRequest(pSlot,SD_API_STATUS_CRC_ERROR);
return TRUE;
}
if (status & SD_Int_Data_Timeout) {
DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: Data Timeout %08X\r\n"),pSlot->SlotNumber,status));
CompleteRequest(pSlot,SD_API_STATUS_DATA_TIMEOUT);
return TRUE;
}
if (status & SD_Int_Response_Timeout) {
DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: Response Timeout %08X\r\n"),pSlot->SlotNumber,status));
CompleteRequest(pSlot,SD_API_STATUS_RESPONSE_TIMEOUT);
return TRUE;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// HandleResponseTimeout - handle response timeout interrupt
// Input: pSlot - slot context
// Output:
// Return:
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID HandleResponseTimeout(PSDIO_SLOT pSlot)
{
// this should never happen because we mark the request as un-cancelable
if (NULL==pSlot->pCurrentRequest) {
return;
}
// turn off response end / response timeout interrupts
SD_INTERRUPTS_DISABLE(pSlot, SD_Int_Response_Done | SD_Int_Response_Timeout);
// clear
SD_INTERRUPTS_CLEAR(pSlot, SD_Int_Response_Done | SD_Int_Response_Timeout);
// complete request with timeout indication
CompleteRequest(pSlot, SD_API_STATUS_RESPONSE_TIMEOUT);
}
///////////////////////////////////////////////////////////////////////////////
// HandleDataTimeout - handle data timeout interrupt
// Input: pSlot - slot context
// Output:
// Return:
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID HandleDataTimeout(PSDIO_SLOT pSlot)
{
// this should never happen because we mark the request as un-cancelable
if (NULL==pSlot->pCurrentRequest) {
return;
}
// turn off interrupts
SD_INTERRUPTS_DISABLE(pSlot, ( SD_Int_Rx_FIFO_Not_Empty
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -