📄 irfir.cpp
字号:
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, 2005, 2006 Freescale Semiconductor, Inc. All Rights Reserved
// THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
// BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
// FREESCALE SEMICONDUCTOR, INC.
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// File: irfir.cpp
//
// This file implements the device specific functions for zeus fir device.
//
//------------------------------------------------------------------------------
#include "IrFir.h"
//------------------------------------------------------------------------------
// External Functions
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Defines
#ifdef DEBUG
DBGPARAM dpCurSettings =
{
TEXT("FIR"),
{
TEXT("Init"), TEXT("Deinit"),
TEXT("Receive"), TEXT("Send"),
TEXT("SetInfo"), TEXT("QueryInfo"),
TEXT("Thread"), TEXT("Open"),
TEXT("Close"), TEXT("CommMask"),
TEXT("Undefined"), TEXT("Misc"),
TEXT("Alloc"), TEXT("Function"),
TEXT("Warning"), TEXT("Error")
},
0x0000C003
};
#endif // DEBUG
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
// Local Variables
// We keep a linked list of device objects
pFirDevice_t gFirstFirDevice = NULL;
static const UINT
v_rgSupportedOids[] =
{
// General required OIDs.
// Query Set Bytes
// supported supported required
// ----------- ----------- ----------
OID_GEN_SUPPORTED_LIST, // Query Arr(4)
OID_GEN_MEDIA_IN_USE, // Query Arr(4)
OID_GEN_MAXIMUM_LOOKAHEAD, // Query 4
OID_GEN_MAXIMUM_FRAME_SIZE, // Query 4
OID_GEN_VENDOR_DRIVER_VERSION, // Query 2
OID_GEN_CURRENT_PACKET_FILTER, // Query Set 4
OID_GEN_MAC_OPTIONS, // Query 4
OID_GEN_MAXIMUM_SEND_PACKETS, // Query 4
// Infrared-specific OIDs.
OID_IRDA_RECEIVING, // Query 4
OID_IRDA_TURNAROUND_TIME, // Query 4
OID_IRDA_SUPPORTED_SPEEDS, // Query Arr(4)
OID_IRDA_LINK_SPEED, // Query Set 4
OID_IRDA_MEDIA_BUSY, // Query Set 4
OID_IRDA_EXTRA_RCV_BOFS, // Query 4
OID_IRDA_REACQUIRE_HW_RESOURCES, // Set 4
OID_IRDA_RELEASE_HW_RESOURCES, // Query 4
// Powermanagement specific OIDs
OID_PNP_CAPABILITIES, // Query
OID_PNP_SET_POWER, // Query Set
OID_PNP_QUERY_POWER, // Query
OID_PNP_ADD_WAKE_UP_PATTERN, // Query Set
OID_PNP_REMOVE_WAKE_UP_PATTERN, // Query Set
OID_PNP_ENABLE_WAKE_UP // Query Set
};
//------------------------------------------------------------------------------
// Local Functions
//-----------------------------------------------------------------------------
//
// Function: DllEntry
//
// This function is entry point of the dll.
//
// Parameters:
// hInstDll
// [in] .
// Op
// [in] .
// lpvReserved
// [in] .
//
// Returns:
// This function always returns TRUE.
//
//-----------------------------------------------------------------------------
BOOL WINAPI DllEntry( HANDLE hInstDll, DWORD Op, LPVOID lpvReserved )
{
switch(Op)
{
case DLL_PROCESS_ATTACH:
DEBUGMSG(ZONE_INIT, (TEXT("IrFir: DLL Process Attach.\r\n")));
// Register debug zones
DEBUGREGISTER((HMODULE)hInstDll);
// Disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications
DisableThreadLibraryCalls((HMODULE) hInstDll);
break;
case DLL_PROCESS_DETACH:
DEBUGMSG(ZONE_INIT, (TEXT("IrFir: DLL Process Detach.\r\n")));
break;
default:
break;
}
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: DriverEntry
//
// This function is the entry point of the FIR Miniport NDIS driver.
//
// Parameters:
// DriverObject
// [in] .
// RegistryPath
// [in] .
//
// Returns:
//
//-----------------------------------------------------------------------------
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
NDIS_STATUS status;
NDIS_HANDLE hWrapper;
NDIS50_MINIPORT_CHARACTERISTICS IrFir;
DEBUGMSG(ZONE_INIT, (TEXT("IrFir: +DriverEntry(0x%.8X, 0x%.8X)\r\n"), DriverObject, RegistryPath));
// Initialize the wrapper.
NdisMInitializeWrapper(&hWrapper, DriverObject, RegistryPath, NULL);
// Setup the NDIS characteristics of this miniport driver
NdisZeroMemory( &IrFir, sizeof(IrFir));
IrFir.Ndis40Chars.Ndis30Chars.MajorNdisVersion = NDIS_MAJOR_VERSION;
IrFir.Ndis40Chars.Ndis30Chars.MinorNdisVersion = NDIS_MINOR_VERSION;
IrFir.Ndis40Chars.Ndis30Chars.InitializeHandler = IrFirInitialize;
IrFir.Ndis40Chars.Ndis30Chars.CheckForHangHandler = IrFirCheckForHang;
IrFir.Ndis40Chars.Ndis30Chars.DisableInterruptHandler = IrFirDisableInterrupt;
IrFir.Ndis40Chars.Ndis30Chars.EnableInterruptHandler = IrFirEnableInterrupt;
IrFir.Ndis40Chars.Ndis30Chars.HaltHandler = IrFirHalt;
IrFir.Ndis40Chars.Ndis30Chars.HandleInterruptHandler = IrFirHandleInterrupt;
IrFir.Ndis40Chars.Ndis30Chars.ISRHandler = NULL;
IrFir.Ndis40Chars.Ndis30Chars.QueryInformationHandler = IrFirQueryInformation;
IrFir.Ndis40Chars.Ndis30Chars.ReconfigureHandler = NULL;
IrFir.Ndis40Chars.Ndis30Chars.ResetHandler = IrFirReset;
IrFir.Ndis40Chars.Ndis30Chars.SendHandler = IrFirSend;
IrFir.Ndis40Chars.Ndis30Chars.SetInformationHandler = IrFirSetInformation;
IrFir.Ndis40Chars.Ndis30Chars.TransferDataHandler = NULL;
IrFir.Ndis40Chars.ReturnPacketHandler = IrFirReturnPacket;
IrFir.Ndis40Chars.SendPacketsHandler = NULL;
IrFir.Ndis40Chars.AllocateCompleteHandler = NULL;
status = NdisMRegisterMiniport(hWrapper, &IrFir, sizeof(IrFir));
if (status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_INIT, (TEXT("IrFir: -DriverEntry [%s]\r\n"), DBG_NDIS_RESULT_STR(status)));
NdisTerminateWrapper(hWrapper, NULL);
}
DEBUGMSG(ZONE_INIT, (TEXT("IrFir: -DriverEntry [%s]\r\n"), DBG_NDIS_RESULT_STR(status)));
return (status);
}
//-----------------------------------------------------------------------------
//
// Function: IrFirTimer
//
// This function is to handle the delayed packet sending specified by Irda protocol.
//
// Parameters:
// SystemSpecific1
// [in] .
// FunctionContext
// [in] .
// SystemSpecific2
// [in] .
// SystemSpecific3
// [in] .
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID IrFirTimer( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3 )
{
pFirDevice_t thisDev = (pFirDevice_t)FunctionContext;
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: +IrFirTimer timeout\r\n")));
NdisAcquireSpinLock(&thisDev->Lock);
//Kick off another Tx
thisDev->IR_VTbl->m_pDelayedSendPacket(thisDev, TRUE);
NdisReleaseSpinLock(&thisDev->Lock);
}
//-----------------------------------------------------------------------------
//
// Function: ReleaseAdapterResources
//
// This function release the hardware resources when requested.
//
// Parameters:
// pvContext
// [in] .
//
// Returns:
//
//-----------------------------------------------------------------------------
DWORD ReleaseAdapterResources( PVOID pvContext )
{
pFirDevice_t thisDev = (pFirDevice_t)pvContext;
DEBUGMSG(ZONE_THREAD, (TEXT("IrFir: +ReleaseAdapterResources(%#x)\r\n"), thisDev));
// Wait for all packets to be sent and returned.
while (1)
{
NdisAcquireSpinLock(&thisDev->Lock);
if (IsListEmpty(&thisDev->SendQueue) == TRUE && thisDev->writePending == FALSE)
break;
DEBUGMSG(ZONE_THREAD, (TEXT("IrFir: Release Adpater- I can't release HW. %d\r\n"), thisDev->writePending));
NdisReleaseSpinLock(&thisDev->Lock);
Sleep(100);
}
// Disable interrupt first
thisDev->IR_VTbl->m_pDisableInterrupt(thisDev);
// Need to indicate that we are releasing resources now so the ISR
// does not try to perform any real operations.
thisDev->resourcesReleased = TRUE;
thisDev->IR_VTbl->m_pReleaseAdapterResources(thisDev);
// Indicate success back to protocol.
NdisReleaseSpinLock(&thisDev->Lock);
NdisMQueryInformationComplete(thisDev->ndisAdapterHandle, NDIS_STATUS_SUCCESS);
DEBUGMSG(ZONE_THREAD, (TEXT("IrFir: -ReleaseAdapterResources(%#x)\r\n"), thisDev));
return 0;
}
//-----------------------------------------------------------------------------
//
// Function: IrFirInitialize
//
// This function initializes the Fir device.
//
// Parameters:
// OpenErrorStatus
// [out] .
// SelectedMediumIndex
// [out] .
// MediumArray
// [in] .
// MediumArraySize
// [in] .
// MiniportAdapterHandle
// [in] .
// WrapperConfigurationContext
// [in] .
//
// Returns:
// This function returns the status of initialization.
//
//-----------------------------------------------------------------------------
NDIS_STATUS IrFirInitialize( OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray, IN UINT MediumArraySize, IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE WrapperConfigurationContext )
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
pFirDevice_t thisDev = NULL;
UINT mediumIndex;
DEBUGMSG(ZONE_INIT, (TEXT("IrFir: +IrFirInitialize()\r\n")));
// Search the passed-in array of supported media for the IrDA medium.
for (mediumIndex = 0; mediumIndex < MediumArraySize; mediumIndex++)
{
if (MediumArray[mediumIndex] == NdisMediumIrda)
break;
}
if (mediumIndex < MediumArraySize)
{
*SelectedMediumIndex = mediumIndex;
}
else
{
// IrDA medium not found
DEBUGMSG(ZONE_WARN, (TEXT("IrFir: Didn't see the IRDA medium in IrFirInitialize\r\n")));
status = NDIS_STATUS_UNSUPPORTED_MEDIA;
goto done;
}
// Allocate a new device object to represent this connection.
thisDev = NewDevice();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -