?? sdio.c
字號:
| SD_Int_Tx_Empty
| SD_Int_Data_Timeout ));
// clear interrupts
SD_INTERRUPTS_CLEAR(pSlot, ( SD_Int_Rx_FIFO_Not_Empty
| SD_Int_Tx_Empty
| SD_Int_Data_Timeout ));
// complete request with timeout indication
CompleteRequest(pSlot, SD_API_STATUS_DATA_TIMEOUT);
}
///////////////////////////////////////////////////////////////////////////////
// HandleResponseDone - handle response done interrupt
// Input: pSlot - slot context
// Output:
// Return:
// Notes: Completes the following requests:
// Requests with no data phase
// Requests with a CRC/timeout error in command/response phase
///////////////////////////////////////////////////////////////////////////////
VOID HandleResponseDone(PSDIO_SLOT pSlot)
{
PSD_BUS_REQUEST pRequest; // current request
ULONG response[4];
pRequest = pSlot->pCurrentRequest;
if (NULL==pRequest) {
return;
}
// Turn off response end interrupt
SD_INTERRUPTS_DISABLE(pSlot, SD_Int_Response_Done);
// Clear interrupt
SD_INTERRUPTS_CLEAR(pSlot, SD_Int_Response_Done);
response[0] = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp0);
response[1] = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp1);
response[2] = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp2);
response[3] = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp3);
DEBUGMSG(SDIO_RESPONSE_ZONE, (TEXT("HandleResponseDone SD_RESP0: 0x%08X \n"),response[0]));
DEBUGMSG(SDIO_RESPONSE_ZONE, (TEXT("HandleResponseDone SD_RESP1: 0x%08X \n"),response[1]));
DEBUGMSG(SDIO_RESPONSE_ZONE, (TEXT("HandleResponseDone SD_RESP2: 0x%08X \n"),response[2]));
DEBUGMSG(SDIO_RESPONSE_ZONE, (TEXT("HandleResponseDone SD_RESP3: 0x%08X \n"),response[3]));
if (NoResponse != pRequest->CommandResponse.ResponseType) {
// Copy response over to request structure
PUCHAR pResponseBuffer = &(pRequest->CommandResponse.ResponseBuffer[1]);
int ii;
for (ii=0; ii<4; ii++) {
*pResponseBuffer++ = (UCHAR)(response[ii]);
*pResponseBuffer++ = (UCHAR)(response[ii] >> 8);
*pResponseBuffer++ = (UCHAR)(response[ii] >> 16);
*pResponseBuffer++ = (UCHAR)(response[ii] >> 24);
}
}
// check for command/response only
if (SD_COMMAND == pRequest->TransferClass) {
// check for and handle errors
if (FALSE==HandleTransferErrors(pSlot,pRequest,SD_Int_Response_CRC_Error)) {
// no errors, complete request with success
CompleteRequest(pSlot, SD_API_STATUS_SUCCESS);
}
} else {
#ifdef USE_DMA
if (!pSlot->UsingDmaThisCmd) {
#endif // #ifdef USE_DMA
// handle data phase transfer
// set blocks transferred to 0
((PHC_PARAMS)pRequest->HCParam)->BytesCopied = 0;
if (TRANSFER_IS_READ(pRequest)) {
// Enable buffer read enable interrupt
SD_INTERRUPTS_ENABLE(pSlot, SD_Int_Rx_FIFO_Not_Empty |
SD_Int_Data_Timeout);
} else {
// Enable buffer write enable interrupt
SD_INTERRUPTS_ENABLE(pSlot, SD_Int_Tx_Empty |
SD_Int_Data_Timeout);
}
#ifdef USE_DMA
} else {
if (TRANSFER_IS_READ(pRequest)) {
HalStartDMA(pSlot->RxDmaChannel);
} else {
HalStartDMA(pSlot->TxDmaChannel);
}
}
#endif // #ifdef USE_DMA
}
}
///////////////////////////////////////////////////////////////////////////////
// HandleRxFifoNotEmpty - handle Rx FIFO not empty interrupt
// Input: pSlot - slot context
// Output:
// Return:
// Notes: Completes the following requests:
// Requests with a CRC/timeout error in the read data phase
///////////////////////////////////////////////////////////////////////////////
VOID HandleRxFifoNotEmpty(PSDIO_SLOT pSlot)
{
PSD_BUS_REQUEST pRequest; // current request
ULONG regValue; // reg value
// get the current request
pRequest = pSlot->pCurrentRequest;
if (NULL==pRequest) {
return;
}
if (((PHC_PARAMS)pRequest->HCParam)->BytesCopied == (pRequest->BlockSize*pRequest->NumBlocks)) {
return;
}
// we are touching the block buffer, we must set the process permissions
SD_SET_PROC_PERMISSIONS_FROM_REQUEST(pRequest) {
while( (READ_REGISTER_ULONG((PULONG)&pSlot->pSD->status) & SD_Int_Rx_FIFO_Not_Empty) &&
(((PHC_PARAMS)pRequest->HCParam)->BytesCopied < (pRequest->BlockSize*pRequest->NumBlocks))) {
// Get byte from fifo
regValue = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->rxport);
pRequest->pBlockBuffer[((PHC_PARAMS)pRequest->HCParam)->BytesCopied] = (UCHAR)(regValue&0xFF);
((PHC_PARAMS)pRequest->HCParam)->BytesCopied++;
}
} SD_RESTORE_PROC_PERMISSIONS();
if (((PHC_PARAMS)pRequest->HCParam)->BytesCopied == (pRequest->BlockSize*pRequest->NumBlocks)) {
SD_INTERRUPTS_DISABLE(pSlot,SD_Int_Rx_FIFO_Not_Empty);
DEBUGMSG(SDIO_INTERRUPT_ZONE,(TEXT("SDIO: RxFifoNotEmpty completing request, HCParam=%d\r\n"),((PHC_PARAMS)pRequest->HCParam)->BytesCopied));
// check for and handle errors
if (FALSE==HandleTransferErrors(pSlot,pRequest,SD_Int_Read_CRC_Error)) {
// no errors, complete request with success
CompleteRequest(pSlot, SD_API_STATUS_SUCCESS);
}
}
}
///////////////////////////////////////////////////////////////////////////////
// HandleTxEmpty - handle Tx empty interrupt
// Input: pSlot - slot context
// Output:
// Return: TRUE if the request has been completed
// Notes: Completes the following requests:
// Requests with a CRC/timeout error in the read data phase
///////////////////////////////////////////////////////////////////////////////
VOID HandleTxEmpty(PSDIO_SLOT pSlot)
{
PSD_BUS_REQUEST pRequest; // current request
ULONG dataValue; // reg value
// get the current request
pRequest = pSlot->pCurrentRequest;
// check the request hasn't already been completed
if ((NULL==pRequest) || (((PHC_PARAMS)pRequest->HCParam)->BytesCopied == (pRequest->BlockSize*pRequest->NumBlocks))) {
SD_INTERRUPTS_DISABLE(pSlot,SD_Int_Tx_Empty);
return;
}
// we are touching the block buffer, we must set the process permissions
SD_SET_PROC_PERMISSIONS_FROM_REQUEST(pRequest) {
while( (READ_REGISTER_ULONG((PULONG)&pSlot->pSD->status) & SD_Int_Tx_Empty) &&
(((PHC_PARAMS)pRequest->HCParam)->BytesCopied < (pRequest->BlockSize*pRequest->NumBlocks))) {
// Get byte from buffer
dataValue = pRequest->pBlockBuffer[((PHC_PARAMS)pRequest->HCParam)->BytesCopied];
WRITE_REGISTER_ULONG((PULONG)&pSlot->pSD->txport,dataValue);
((PHC_PARAMS)pRequest->HCParam)->BytesCopied++;
}
} SD_RESTORE_PROC_PERMISSIONS();
if (((PHC_PARAMS)pRequest->HCParam)->BytesCopied == (pRequest->BlockSize*pRequest->NumBlocks)) {
SD_INTERRUPTS_DISABLE(pSlot,SD_Int_Tx_Empty);
// check for and handle errors
if (FALSE==HandleTransferErrors(pSlot,pRequest,SD_Int_Write_CRC_Error)) {
// no errors, complete request with success
CompleteRequest(pSlot, SD_API_STATUS_SUCCESS);
}
}
}
///////////////////////////////////////////////////////////////////////////////
// GetInterrupts - get current pending interrupts
// Input: pSlot - slot context
// Output: pInterrupts - active, unmasked, controller interrupts
// Return: TRUE if there is an active unmasked interrupt
// Notes:
///////////////////////////////////////////////////////////////////////////////
BOOL GetInterrupts(PSDIO_SLOT pSlot,
PULONG pInterrupts)
{
ULONG interrupts; // controller interrupts
// read interrupts from hardware
interrupts = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->status);
// the hardware masks interrupts sources from causing an interrupt,
// but not from showing up in the status register. Mask them here.
interrupts &= pSlot->InterruptMask;
*pInterrupts = interrupts;
// Return TRUE if any unmasked interrupts are active
return (0 != interrupts);
}
///////////////////////////////////////////////////////////////////////////////
// SDIOInsertionIstThread - IST thread for driver
// Input: pSlot - slot context
// Output:
// Notes:
///////////////////////////////////////////////////////////////////////////////
DWORD SDIOInsertionIstThread(PSDIO_SLOT pSlot)
{
DWORD waitStatus; // wait status
DWORD initRate = 200000;
int debounceCount;
BOOL cardInserted;
if (!CeSetThreadPriority(GetCurrentThread(), pSlot->InsertionIstThreadPriority)) {
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDIOInsertionIstThread[%d]: warning, failed to set CEThreadPriority \n"),pSlot->SlotNumber));
}
while(1) {
waitStatus = WaitForSingleObject(pSlot->hInsertionInterruptEvent, INFINITE);
if (WAIT_OBJECT_0 != waitStatus) {
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDIOInsertionIstThread[%d]: Wait Failed! 0x%08X \n"),pSlot->SlotNumber, waitStatus));
// bail out
return 0;
}
if (pSlot->pController->DriverShutdown) {
DEBUGMSG(1, (TEXT("SDIOInsertionIstThread[%d]: Thread Exiting\n"),pSlot->SlotNumber));
return 0;
}
// check slot on startup for inserted cards
if (pSlot->CheckSlotOnStartUp) {
DEBUGMSG(SDIO_INTERRUPT_ZONE,(TEXT("SDIOInsertionIstThread[%d]: Removing device after powerdown\r\n"),pSlot->SlotNumber));
// this case is hit when we suspend and resume while there is a
// card in the slot, because we remove power we have
// to indicate a device removal first
RemoveDevice(pSlot);
// Reset the slot
ResetSlot(pSlot, FALSE);
#ifdef DEBUG
// Dump the state of the slot
DumpSlot(pSlot);
#endif
// Now check to see if the card is still present, if so
// handle as per device insertion
if (SDIOPlatCardInserted(pSlot->pController,pSlot->SlotNumber)) {
pSlot->CardPresent = TRUE;
pSlot->CardInitialised = FALSE;
// indicate device arrival
SDHCDIndicateSlotStateChange(pSlot->pController->pHCContext,
pSlot->SlotNumber,
DeviceInserted );
} else {
pSlot->CardPresent = FALSE;
}
pSlot->CheckSlotOnStartUp = FALSE;
InterruptDone(pSlot->InsertionSysIntr);
continue;
}
DEBUGMSG(SDIO_INTERRUPT_ZONE, (TEXT("SDIOInsertionIstThread[%d]: interrupt!\n"),pSlot->SlotNumber));
// start debounce logic
debounceCount = 0;
cardInserted = FALSE;
// stay in this loop until the insertion state has been the same for
// ten consecutive debounce sampling intervals
while(debounceCount < SDIO_DEBOUNCE_COUNT) {
if (SDIOPlatCardInserted(pSlot->pController,pSlot->SlotNumber)) {
if (cardInserted) {
debounceCount++;
} else {
cardInserted = TRUE;
debounceCount = 0;
}
} else {
if (cardInserted) {
cardInserted = FALSE;
debounceCount = 0;
} else {
debounceCount++;
}
}
Sleep(SDIO_DEBOUNCE_INTERVAL);
}
if (cardInserted && !pSlot->CardPresent) {
// set clock to 100 kHz for card initialisation
SDIOSetRate(pSlot, &initRate);
pSlot->CardPresent = TRUE;
pSlot->CardInitialised = FALSE;
DEBUGMSG(SDIO_INTERRUPT_ZONE,(TEXT("SDIOInsertionIstThread[%d]: Card Insertion Interrupt\r\n"),pSlot->SlotNumber));
// indicate device arrival
SDHCDIndicateSlotStateChange(pSlot->pController->pHCContext,
pSlot->SlotNumber,
DeviceInserted );
} else if (!cardInserted && pSlot->CardPresent) {
DEBUGMSG(SDIO_INTERRUPT_ZONE,(TEXT("SDIOInsertionIstThread[%d]: Card Removal Interrupt\r\n"),pSlot->SlotNumber));
// remove device
RemoveDevice(pSlot);
pSlot->CardPresent = FALSE;
}
InterruptDone(pSlot->InsertionSysIntr);
}
}
///////////////////////////////////////////////////////////////////////////////
// SDIOControllerIstThread - IST thread for driver
// Input: pController - controller context
// Output:
// Notes:
////////////////////////////////////////////////////////////////////////
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -