📄 miniport.c
字号:
{
if ( psConfigParm->ParameterType == NdisParameterString &&
psConfigParm->ParameterData.StringData.Length > 0 &&
psConfigParm->ParameterData.StringData.Length <= sizeof(psAdapter->wActivePath) )
{
NdisMoveMemory( psAdapter->wActivePath,
psConfigParm->ParameterData.StringData.Buffer,
psConfigParm->ParameterData.StringData.Length );
DBG_LEV1(("Active path retrieved.\n"));
#ifdef CA_CE5
// ERI We need allocate the memory space for calling NidsWriteConfiguration on WinCE 5.0.
// Otherwise, the system should be halted
iStatus = NdisAllocateMemoryWithTag( &pvBuffer,
psConfigParm->ParameterData.StringData.Length, 'fwAC' );
if ( iStatus != NDIS_STATUS_SUCCESS )
{
DBG_LEV0(("ERROR: Couldn't allocate memory for configuration parameter!\n"));
return( iStatus );
}
#endif
// Reset the value.
sWriteConfigParm.ParameterData.StringData.Buffer = pvBuffer;
sWriteConfigParm.ParameterData.StringData.Length = 0;
sWriteConfigParm.ParameterType = NdisParameterString;
NdisWriteConfiguration( &iStatus, hRegistryHandle, &nsActivePathKey, &sWriteConfigParm );
#ifdef CA_CE5
// ERI Release the memory space
NdisFreeMemory( pvBuffer, psConfigParm->ParameterData.StringData.Length, 0 );
#endif
// Get SDIO device handle.
psAdapter->hSDDeviceHandle = SDGetDeviceHandle( (DWORD)psAdapter->wActivePath, NULL );
if ( !psAdapter->hSDDeviceHandle )
{
DBG_LEV0(("ERROR: Failed to get SDIO device handle.\n"));
iStatus = NDIS_STATUS_FAILURE;
}
}
else
{
DBG_LEV0(("ERROR: Wrong active path key parameter.\n"));
iStatus = NDIS_STATUS_FAILURE;
}
}
else
{
DBG_LEV0(("ERROR: Failed to get active path key.\n"));
}
return( iStatus );
}
/*****************************************************************************
**
** NAME iENDinitializeSDIO
**
** PARAMETERS psAdapter Pointer to Adapter context.
**
** RETURNS NDIS_STATUS_SUCCESS or error code.
**
** DESCRIPTION This function initializes SDIO.
**
******************************************************************************/
NDIS_STATUS
iENDinitializeSDIO( IN OUT PEND_CONTEXT psAdapter )
{
PHAL_CONTEXT psHAL = &psAdapter->sHAL;
NDIS_STATUS iStatus = NDIS_STATUS_FAILURE;
SDCARD_CLIENT_REGISTRATION_INFO sClientInfo;
SD_API_STATUS iSDStatus;
SD_IO_FUNCTION_ENABLE_INFO sFunctionEnable;
SD_CARD_INTERFACE sCardInterface;
SDIO_CARD_INFO sSDIOInfo;
DWORD ulBlockLength;
do {
if ( !psAdapter->boResetInProgress )
{
NdisZeroMemory( &sClientInfo, sizeof(SDCARD_CLIENT_REGISTRATION_INFO) );
// Set client options and register as a client device.
_tcscpy( sClientInfo.ClientName, TEXT("Freescale Waveblaster SDIO NDIS") );
// Set the event callback.
sClientInfo.pSlotEventCallBack = vENDslotEventSDIO;
iSDStatus = SDRegisterClient( psAdapter->hSDDeviceHandle, psAdapter, &sClientInfo );
if ( !SD_API_SUCCESS(iSDStatus) )
{
DBG_LEV0(("ERROR: Failed to register client: 0x%x.\n", iSDStatus));
break;
}
}
// Setup the function enable structure.
// TODO: use the appropriate retry and interval count for the function.
sFunctionEnable.Interval = 500;
sFunctionEnable.ReadyRetryCount = 3;
// Turn on our function.
iSDStatus = SDSetCardFeature( psAdapter->hSDDeviceHandle,
SD_IO_FUNCTION_ENABLE,
&sFunctionEnable,
sizeof(SD_IO_FUNCTION_ENABLE_INFO) );
if ( !SD_API_SUCCESS(iSDStatus) )
{
DBG_LEV0(("ERROR: Failed to enable function: 0x%x.\n", iSDStatus));
break;
}
// Query the card interface.
iSDStatus = SDCardInfoQuery( psAdapter->hSDDeviceHandle,
SD_INFO_CARD_INTERFACE,
&sCardInterface,
sizeof(SD_CARD_INTERFACE) );
if ( !SD_API_SUCCESS(iSDStatus) )
{
DBG_LEV0(("ERROR: Failed to query interface: 0x%x.\n", iSDStatus));
break;
}
if ( sCardInterface.ClockRate == 0 )
{
DBG_LEV0(("ERROR: Device interface clock rate is zero.\n"));
break;
}
if (sCardInterface.ClockRate > psHAL->ulMaxClockFreq)
{
sCardInterface.ClockRate = psHAL->ulMaxClockFreq;
}
DBG_LEV1(("SDIO interface clock %d Hz.\n", sCardInterface.ClockRate));
if ( sCardInterface.InterfaceMode == SD_INTERFACE_SD_MMC_1BIT )
{
DBG_LEV1(("SDIO 1 bit interface mode.\n"));
}
else if ( sCardInterface.InterfaceMode == SD_INTERFACE_SD_4BIT )
{
if (psHAL->boSupport4BitMode)
{
DBG_LEV1(("SDIO 4 bit interface mode.\n"));
}
else
{
DBG_LEV1(("SDIO 4 bit interface mode, set to 1 bit mode.\n"));
// Set to 1 bit mode.
sCardInterface.InterfaceMode = SD_INTERFACE_SD_MMC_1BIT;
}
}
else
{
DBG_LEV0(("ERROR: SDIO unknown interface mode.\n"));
break;
}
iSDStatus = SDSetCardFeature( psAdapter->hSDDeviceHandle,
SD_SET_CARD_INTERFACE,
&sCardInterface,
sizeof(SD_CARD_INTERFACE) );
if ( !SD_API_SUCCESS(iSDStatus) )
{
DBG_LEV0(("ERROR: Failed to set clock rate and bit width: 0x%x.\n", iSDStatus));
break;
}
// Query the SDIO information.
iSDStatus = SDCardInfoQuery( psAdapter->hSDDeviceHandle,
SD_INFO_SDIO,
&sSDIOInfo,
sizeof(SDIO_CARD_INFO) );
if ( !SD_API_SUCCESS(iSDStatus) )
{
DBG_LEV0(("ERROR: Failed to query SDIO info: 0x%x.\n", iSDStatus));
break;
}
DBG_LEV1(("SDIO info: function number %d.\n", sSDIOInfo.FunctionNumber));
DBG_LEV1(("SDIO info: device code %d.\n", sSDIOInfo.DeviceCode));
DBG_LEV1(("SDIO info: CIS pointer 0x%08x.\n", sSDIOInfo.CISPointer));
DBG_LEV1(("SDIO info: CSA pointer 0x%08x.\n", sSDIOInfo.CSAPointer));
DBG_LEV1(("SDIO info: card capability 0x%02x.\n", sSDIOInfo.CardCapability));
if ( (sSDIOInfo.FunctionNumber != 1) ||
(sSDIOInfo.CISPointer == 0) || (sSDIOInfo.CardCapability == 0) )
{
DBG_LEV0(("ERROR: Wrong SDIO info.\n"));
break;
}
// Set the block length for this function.
ulBlockLength = psHAL->ulBlockSize;
iSDStatus = SDSetCardFeature( psAdapter->hSDDeviceHandle,
SD_IO_FUNCTION_SET_BLOCK_SIZE,
&ulBlockLength,
sizeof(DWORD) );
if ( !SD_API_SUCCESS(iSDStatus) )
{
DBG_LEV0(("ERROR: Failed to set block length: 0x%x.\n", iSDStatus));
break;
}
DBG_LEV1(("Set SDIO block length to %d.\n", ulBlockLength));
// Connect the interrupt callback.
iSDStatus = SDIOConnectInterrupt( psAdapter->hSDDeviceHandle,
(PSD_INTERRUPT_CALLBACK)iENDinterruptSDIO );
if ( !SD_API_SUCCESS(iSDStatus) )
{
DBG_LEV0(("ERROR: Failed to connect interrupt: 0x%x.\n", iSDStatus));
break;
}
if ( !psAdapter->boResetInProgress )
{
// Initialize a timer for interrupt DPC.
NdisMInitializeTimer( &psAdapter->sSDIOTimer,
psAdapter->hMiniportAdapterHandle,
(PNDIS_TIMER_FUNCTION) vENDhandleInterruptSDIO,
(PVOID) psAdapter);
}
DBG_LEV1(("Connected SDIO interrupt and intialized interrupt timer.\n"));
iStatus = NDIS_STATUS_SUCCESS;
} while (FALSE);
return( iStatus );
}
/*****************************************************************************
**
** NAME vENDslotEventSDIO
**
** PARAMETERS hSDDevice SDIO device handle.
** psFuncContext Pointer to Adapter context.
** iSlotEventType Slot event type.
** pData Slot event data (can be NULL).
** ulDataLength Length of slot event data (can be 0).
**
** DESCRIPTION SDIO slot event (such as device remove) callback.
** This callback must not perform any bus requests.
**
******************************************************************************/
VOID
vENDslotEventSDIO( IN SD_DEVICE_HANDLE hSDDevice, IN PVOID psFuncContext,
IN SD_SLOT_EVENT_TYPE iSlotEventType, IN PVOID pData, DWORD ulDataLength )
{
PEND_CONTEXT psAdapter = (PEND_CONTEXT)psFuncContext;
DBG_LEV1(("SDIO slot event %d\n", iSlotEventType));
if ( iSlotEventType = SDCardEjected )
{
// Disconnect interrupt.
SDIODisconnectInterrupt( hSDDevice );
if ( psAdapter->boSDIOTimerIssued )
{
BOOLEAN boTimerCancelled;
// Cancel timer.
NdisMCancelTimer( &psAdapter->sSDIOTimer, &boTimerCancelled );
}
// Set card state to STOPPED to block further device access.
psAdapter->sHAL.eState = HAL_STOPPED;
}
return;
}
/*****************************************************************************
**
** NAME iENDinterruptSDIO
**
** PARAMETERS hSDDevice SDIO device handle.
** psFuncContext Pointer to Adapter context.
**
** DESCRIPTION SDIO interrupt callback. Schedule a timer to handle interrupt.
**
******************************************************************************/
SD_API_STATUS
iENDinterruptSDIO( IN SD_DEVICE_HANDLE hSDDevice, IN PVOID psFuncContext )
{
PEND_CONTEXT psAdapter = (PEND_CONTEXT)psFuncContext;
BOOLEAN boInterruptRecognized, boQueueMiniportHandleInterrupt;
vHALIsr( &boInterruptRecognized, &boQueueMiniportHandleInterrupt, psFuncContext );
if ( boQueueMiniportHandleInterrupt )
{
// Set a timer to handle interrupt.
NdisMSetTimer( &psAdapter->sSDIOTimer, 0 );
psAdapter->boSDIOTimerIssued = TRUE;
}
return SD_API_STATUS_SUCCESS;
}
/*****************************************************************************
**
** NAME vENDhandleInterruptSDIO
**
** PARAMETERS psFuncContext Pointer to Adapter context.
**
** DESCRIPTION This timer function is scheduled by SDIO interrupt callback.
** Dispatch to handle interrupt sources.
**
******************************************************************************/
VOID
vENDhandleInterruptSDIO( IN PVOID pvSystemSpecific1, IN NDIS_HANDLE psFuncContext,
IN PVOID pvSystemSpecific2, IN PVOID pvSystemSpecific3 )
{
PEND_CONTEXT psAdapter = (PEND_CONTEXT)psFuncContext;
vHALhandleInterrupt( psFuncContext );
psAdapter->boSDIOTimerIssued = FALSE;
}
/*****************************************************************************
**
** NAME vENDreleaseResources
**
** PARAMETERS psAdapter Pointer to Adapter context.
**
** DESCRIPTION This function releases all hardware and software resources.
**
******************************************************************************/
VOID
vENDreleaseResources( IN PEND_CONTEXT psAdapter )
{
UINT uiLoop;
if ( psAdapter != NULL)
{
// Release NDIS packet pool and buffer pool handles.
if ( psAdapter->hRxPacketPool )
{
NdisFreePacketPool( psAdapter->hRxPacketPool );
// We allocate buffer pool before packet pool, so we can free it here.
NdisFreeBufferPool( psAdapter->hRxBufferPool );
}
// Free memory allocated.
for ( uiLoop=0; uiLoop<CFG_NUM_CODE_IMAGES; uiLoop++ )
{
if ( psAdapter->sCFG.asCode[uiLoop].paucImage != NULL )
{
NdisFreeMemory( psAdapter->sCFG.asCode[uiLoop].paucImage,
psAdapter->sCFG.asCode[uiLoop].ulLength, 0 );
}
}
for ( uiLoop=0; uiLoop<psAdapter->sWlan.ulNumOfBssidBuf; uiLoop++ )
{
if (psAdapter->sWlan.sBssidList[uiLoop].psBssid != NULL)
{
NdisFreeMemory( psAdapter->sWlan.sBssidList[uiLoop].psBssid,
sizeof(NDIS_WLAN_BSSID_EX)+END_MAX_IES_SIZE, 0 );
psAdapter->sWlan.sBssidList[uiLoop].psBssid = NULL;
}
}
// Finally release the Adapter context area.
NdisFreeMemory( psAdapter, sizeof(END_CONTEXT), 0 );
}
}
/* End of file CFSD_NDminiport.c. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -