?? sdio.c
字號:
// Initialize channels
HalInitDmaChannel(pSlot->TxDmaChannel,
AuSdConfig[pSlot->SlotNumber].TxDmaDeviceId,
pSlot->DmaBufferSize,
TRUE);
// Initialize channels
HalInitDmaChannel(pSlot->RxDmaChannel,
AuSdConfig[pSlot->SlotNumber].RxDmaDeviceId,
pSlot->DmaBufferSize,
TRUE);
HalSetDMAForReceive(pSlot->RxDmaChannel);
// set up DMA interrupt
hwIntr = HalGetDMAHwIntr(pSlot->TxDmaChannel);
hwIntr |= (HalGetDMAHwIntr(pSlot->RxDmaChannel) << 8);
RETAILMSG(1,(TEXT("SDIO Hooking HWINTR %08X\r\n"),hwIntr));
pSlot->DmaSysIntr = InterruptConnect(Internal, 0, hwIntr, 0);
if (SYSINTR_NOP==pSlot->DmaSysIntr) {
DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: Can't allocate DMA SYSINTR\r\n"),
pSlot->SlotNumber));
goto ErrorReturn;
}
RETAILMSG(1,(TEXT("DmaSysIntr = %X\r\n"),pSlot->DmaSysIntr));
// allocate the dma interrupt event
pSlot->hDmaInterruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (NULL == pSlot->hDmaInterruptEvent) {
DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: Can't create DMA interrupt event\r\n"),
pSlot->SlotNumber));
goto ErrorReturn;
}
if (!InterruptInitialize(pSlot->DmaSysIntr,
pSlot->hDmaInterruptEvent,
NULL,
0)) {
DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: Call to InterruptInitialize failed\r\n"),
pSlot->SlotNumber));
}
pSlot->DmaIstThreadPriority = SDIO_CARD_CONTROLLER_IST_PRIORITY;
// create the interrupt thread for controller interrupts
pSlot->hDmaInterruptThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)SDIODmaIstThread,
pSlot,
0,
&threadID);
if (NULL == pSlot->hDmaInterruptThread) {
DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: Can't create DMA interrupt thread\r\n"),
pSlot->SlotNumber));
goto ErrorReturn;
}
return TRUE;
// post error clean-up from here on...
ErrorReturn:
SDIODeinitializeDMA(pSlot);
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// SDIODeinitializeDMA - De-Initialize the DMA channel
// Input: pSlot - slot context
// Output:
// Return:
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID SDIODeinitializeDMA(PSDIO_SLOT pSlot)
{
InterruptDisable(pSlot->DmaSysIntr);
// free the Tx Channel
if (NULL!=pSlot->TxDmaChannel) {
HalFreeDMAChannel(pSlot->TxDmaChannel);
pSlot->TxDmaChannel = NULL;
}
// free the Rx Channel
if (NULL!=pSlot->RxDmaChannel) {
HalFreeDMAChannel(pSlot->RxDmaChannel);
pSlot->RxDmaChannel = NULL;
}
// clean up DMA IST
if (NULL != pSlot->hDmaInterruptThread) {
// wake up the IST
SetEvent(pSlot->hDmaInterruptEvent);
// wait for the thread to exit
WaitForSingleObject(pSlot->hDmaInterruptThread, INFINITE);
CloseHandle(pSlot->hDmaInterruptThread);
pSlot->hDmaInterruptThread = NULL;
}
// free DMA interrupt event
if (NULL != pSlot->hDmaInterruptEvent) {
CloseHandle(pSlot->hDmaInterruptEvent);
pSlot->hDmaInterruptEvent = NULL;
}
}
#endif // #ifdef USE_DMA
///////////////////////////////////////////////////////////////////////////////
// SendStopTransmission - sends a CMD12 to terminate a write transaction
// Input: pSlot - slot context
// Output:
// Return:
// Notes: This needs to be called in the event of a CRC failure during a
// multiblock write. The Bus Driver will resend the write request
// but the controller state machine needs to receive a CMD12 to
// get it out of the data write state.
///////////////////////////////////////////////////////////////////////////////
VOID SendStopTransmission(PSDIO_SLOT pSlot)
{
ULONG tmp;
// check that data busy is active
if (!(READ_REGISTER_ULONG((PULONG)&pSlot->pSD->status)&SD_STATUS_DB)) {
return;
}
SD_INTERRUPTS_DISABLE(pSlot,SD_Int_Response_Done );
// disable clock freezing
tmp = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->config2);
tmp |= SD_CONFIG2_DF;
WRITE_REGISTER_ULONG((PULONG)&pSlot->pSD->config2,tmp);
// write stop transmission command
WRITE_REGISTER_ULONG((PULONG)&pSlot->pSD->cmd, 0x00810C71);
// wait for response ready
while(!(READ_REGISTER_ULONG((PULONG)&pSlot->pSD->cmd)&SD_CMD_RY)) {};
// read response registers
(void) READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp0);
(void) READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp1);
(void) READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp2);
(void) READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp3);
}
///////////////////////////////////////////////////////////////////////////////
// CompleteRequest - complete a bus reqeust
// Input: pSlot - slot context
// CompletionStatus - status of completing request
// Output:
// Return:
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID CompleteRequest(PSDIO_SLOT pSlot,
SD_API_STATUS CompletionStatus)
{
PSD_BUS_REQUEST pRequest; // the completed request
pRequest = pSlot->pCurrentRequest;
if (NULL==pRequest) {
return;
}
pSlot->pCurrentRequest = NULL;
// turn the clock off
SDIOClockOff(pSlot);
// complete the request
SDHCDIndicateBusRequestComplete(pSlot->pController->pHCContext,
pRequest,
CompletionStatus);
}
///////////////////////////////////////////////////////////////////////////////
// SDIOInitializeSlot - Initialize SD slot
// Input: pSlot - slot context
// Output:
// Return: SD_API_STATUS
// Notes:
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDIOInitializeSlot(PSDIO_SLOT pSlot)
{
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status
DWORD threadID; // thread ID
PHYSICAL_ADDRESS PhysAddr;
// enable slot power
SDIOPlatPower(pSlot->pController,
TRUE,
pSlot->SlotNumber);
// allocate the interrupt event for the slot
pSlot->hInsertionInterruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (NULL == pSlot->hInsertionInterruptEvent) {
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
goto exitInit;
}
// initialize the interrupt event for the slot
if (!InterruptInitialize (pSlot->InsertionSysIntr,
pSlot->hInsertionInterruptEvent,
NULL,
0)) {
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
goto exitInit;
}
pSlot->InsertionIstThreadPriority = SDIO_CARD_CONTROLLER_IST_PRIORITY;
// create the interrupt thread for insertion interrupts
pSlot->hInsertionInterruptThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)SDIOInsertionIstThread,
pSlot,
0,
&threadID);
if (NULL == pSlot->hInsertionInterruptThread) {
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
goto exitInit;
}
PhysAddr.HighPart = 0;
PhysAddr.LowPart = AuSdConfig[pSlot->SlotNumber].SDPhysAddr;
// map the controller registers
pSlot->pSD = MmMapIoSpace(PhysAddr,
sizeof(*pSlot->pSD),
FALSE);
if (NULL == pSlot->pSD) {
DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDIOInitialize - failed to map registers\n")));
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
goto exitInit;
}
#ifdef USE_DMA
// do the dma...
if (pSlot->UsingDma) {
pSlot->DmaBufferSize = DMA_BUFFER_SIZE;
if (!SDIOInitializeDMA(pSlot)) {
pSlot->UsingDma = FALSE;
}
}
#endif
// set the slot to its initial SW state
pSlot->CardPresent = FALSE;
pSlot->pCurrentRequest = NULL;
// reset the slot to its initial state
ResetSlot(pSlot, TRUE);
exitInit:
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDIODeInitializeSlot - De-Initialize SD slot
// Input: pSlot - slot context
// Output:
// Return:
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID SDIODeinitializeSlot(PSDIO_SLOT pSlot)
{
InterruptDisable(pSlot->InsertionSysIntr);
// check for cards in slots
if (pSlot->CardPresent) {
pSlot->CardPresent = FALSE;
// handle remove device
RemoveDevice(pSlot);
}
// clean up insertion IST
if (NULL != pSlot->hInsertionInterruptThread) {
// wake up the IST
SetEvent(pSlot->hInsertionInterruptEvent);
// wait for the thread to exit
WaitForSingleObject(pSlot->hInsertionInterruptThread, INFINITE);
CloseHandle(pSlot->hInsertionInterruptThread);
pSlot->hInsertionInterruptThread = NULL;
}
// free insertion interrupt event
if (NULL != pSlot->hInsertionInterruptEvent) {
CloseHandle(pSlot->hInsertionInterruptEvent);
pSlot->hInsertionInterruptEvent = NULL;
}
// unmap registers
if (NULL != pSlot->pSD) {
MmUnmapIoSpace((PVOID)pSlot->pSD, SD_CONTROL_REGISTERS_LENGTH);
pSlot->pSD = NULL;
}
#ifdef USE_DMA
// deinitialize DMA stuff
if (pSlot->UsingDma) {
SDIODeinitializeDMA(pSlot);
}
#endif
}
///////////////////////////////////////////////////////////////////////////////
// SDIOInitialize - Initialize the controller
// Input: pHCContext - host controller context
// Output:
// Return: SD_API_STATUS
// Notes:
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDIOInitialize(PSDCARD_HC_CONTEXT pHCContext)
{
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status
DWORD threadID; // thread ID
PSDIO_HW_CONTEXT pController; // hardware instance
int i;
pController = GetExtensionFromHCDContext(PSDIO_HW_CONTEXT, pHCContext);
pController->DriverShutdown = FALSE;
pController->Slots[0].pController = pController;
pController->Slots[0].SlotNumber = 0;
pController->Slots[1].pController = pController;
pController->Slots[1].SlotNumber = 1;
// initialize the critical section
InitializeCriticalSection(&(pController->CriticalSection));
// initialize the GPIO driver
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -