+++ /dev/null
-/*++\r
-\r
-Copyright(c) 1992-2000 Microsoft Corporation\r
-\r
-Module Name:\r
-\r
- protocol.c\r
-\r
-Abstract:\r
-\r
- Ndis Intermediate Miniport driver sample. This is a passthru driver.\r
-\r
-Author:\r
-\r
-Environment:\r
-\r
-\r
-Revision History:\r
-\r
-\r
---*/\r
-\r
-\r
-#include "precomp.h"\r
-#pragma hdrstop\r
-\r
-#define MAX_PACKET_POOL_SIZE 0x0000FFFF\r
-#define MIN_PACKET_POOL_SIZE 0x000000FF\r
-\r
-//\r
-// NDIS version as 0xMMMMmmmm, where M=Major/m=minor (0x00050001 = 5.1); \r
-// initially unknown (0)\r
-// \r
-ULONG NdisDotSysVersion = 0x0;\r
-\r
-\r
-#define NDIS_SYS_VERSION_51 0x00050001\r
-\r
-\r
-VOID\r
-PtBindAdapter(\r
- OUT PNDIS_STATUS Status,\r
- IN NDIS_HANDLE BindContext,\r
- IN PNDIS_STRING DeviceName,\r
- IN PVOID SystemSpecific1,\r
- IN PVOID SystemSpecific2\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Called by NDIS to bind to a miniport below.\r
-\r
-Arguments:\r
-\r
- Status - Return status of bind here.\r
- BindContext - Can be passed to NdisCompleteBindAdapter if this call is pended.\r
- DeviceName - Device name to bind to. This is passed to NdisOpenAdapter.\r
- SystemSpecific1 - Can be passed to NdisOpenProtocolConfiguration to read per-binding information\r
- SystemSpecific2 - Unused\r
-\r
-Return Value:\r
-\r
- NDIS_STATUS_PENDING if this call is pended. In this case call NdisCompleteBindAdapter\r
- to complete.\r
- Anything else Completes this call synchronously\r
-\r
---*/\r
-{\r
- NDIS_HANDLE ConfigHandle = NULL;\r
- PNDIS_CONFIGURATION_PARAMETER Param;\r
- NDIS_STRING DeviceStr = NDIS_STRING_CONST("UpperBindings");\r
- NDIS_STRING NdisVersionStr = NDIS_STRING_CONST("NdisVersion");\r
- PADAPT pAdapt = NULL;\r
- NDIS_STATUS Sts;\r
- UINT MediumIndex;\r
- ULONG TotalSize;\r
- BOOLEAN NoCleanUpNeeded = FALSE;\r
-\r
-\r
- UNREFERENCED_PARAMETER(BindContext);\r
- UNREFERENCED_PARAMETER(SystemSpecific2);\r
- \r
- DBGPRINT(("==> Protocol BindAdapter\n"));\r
-\r
- do\r
- {\r
- //\r
- // Access the configuration section for our binding-specific\r
- // parameters.\r
- //\r
- NdisOpenProtocolConfiguration(Status,\r
- &ConfigHandle,\r
- SystemSpecific1);\r
-\r
- if (*Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
- if (NdisDotSysVersion == 0)\r
- {\r
- NdisReadConfiguration(Status,\r
- &Param,\r
- ConfigHandle,\r
- &NdisVersionStr, // "NdisVersion"\r
- NdisParameterInteger);\r
- if (*Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
- \r
- NdisDotSysVersion = Param->ParameterData.IntegerData;\r
- }\r
- \r
-\r
- //\r
- // Read the "UpperBindings" reserved key that contains a list\r
- // of device names representing our miniport instances corresponding\r
- // to this lower binding. Since this is a 1:1 IM driver, this key\r
- // contains exactly one name.\r
- //\r
- // If we want to implement a N:1 mux driver (N adapter instances\r
- // over a single lower binding), then UpperBindings will be a\r
- // MULTI_SZ containing a list of device names - we would loop through\r
- // this list, calling NdisIMInitializeDeviceInstanceEx once for\r
- // each name in it.\r
- //\r
- NdisReadConfiguration(Status,\r
- &Param,\r
- ConfigHandle,\r
- &DeviceStr,\r
- NdisParameterString);\r
- if (*Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
-\r
- //\r
- // Allocate memory for the Adapter structure. This represents both the\r
- // protocol context as well as the adapter structure when the miniport\r
- // is initialized.\r
- //\r
- // In addition to the base structure, allocate space for the device\r
- // instance string.\r
- //\r
- TotalSize = sizeof(ADAPT) + Param->ParameterData.StringData.MaximumLength;\r
-\r
- NdisAllocateMemoryWithTag(&pAdapt, TotalSize, TAG);\r
-\r
- if (pAdapt == NULL)\r
- {\r
- *Status = NDIS_STATUS_RESOURCES;\r
- break;\r
- }\r
-\r
- //\r
- // Initialize the adapter structure. We copy in the IM device\r
- // name as well, because we may need to use it in a call to\r
- // NdisIMCancelInitializeDeviceInstance. The string returned\r
- // by NdisReadConfiguration is active (i.e. available) only\r
- // for the duration of this call to our BindAdapter handler.\r
- //\r
- NdisZeroMemory(pAdapt, TotalSize);\r
- pAdapt->DeviceName.MaximumLength = Param->ParameterData.StringData.MaximumLength;\r
- pAdapt->DeviceName.Length = Param->ParameterData.StringData.Length;\r
- pAdapt->DeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(ADAPT));\r
- NdisMoveMemory(pAdapt->DeviceName.Buffer,\r
- Param->ParameterData.StringData.Buffer,\r
- Param->ParameterData.StringData.MaximumLength);\r
-\r
-\r
-\r
- NdisInitializeEvent(&pAdapt->Event);\r
- NdisAllocateSpinLock(&pAdapt->Lock);\r
-\r
- //\r
- // Allocate a packet pool for sends. We need this to pass sends down.\r
- // We cannot use the same packet descriptor that came down to our send\r
- // handler (see also NDIS 5.1 packet stacking).\r
- //\r
- NdisAllocatePacketPoolEx(Status,\r
- &pAdapt->SendPacketPoolHandle,\r
- MIN_PACKET_POOL_SIZE,\r
- MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,\r
- sizeof(SEND_RSVD));\r
-\r
- if (*Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
-\r
- //\r
- // Allocate a packet pool for receives. We need this to indicate receives.\r
- // Same consideration as sends (see also NDIS 5.1 packet stacking).\r
- //\r
- NdisAllocatePacketPoolEx(Status,\r
- &pAdapt->RecvPacketPoolHandle,\r
- MIN_PACKET_POOL_SIZE,\r
- MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,\r
- PROTOCOL_RESERVED_SIZE_IN_PACKET);\r
-\r
- if (*Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
-\r
- //\r
- // Now open the adapter below and complete the initialization\r
- //\r
- NdisOpenAdapter(Status,\r
- &Sts,\r
- &pAdapt->BindingHandle,\r
- &MediumIndex,\r
- MediumArray,\r
- sizeof(MediumArray)/sizeof(NDIS_MEDIUM),\r
- ProtHandle,\r
- pAdapt,\r
- DeviceName,\r
- 0,\r
- NULL);\r
-\r
- if (*Status == NDIS_STATUS_PENDING)\r
- {\r
- NdisWaitEvent(&pAdapt->Event, 0);\r
- *Status = pAdapt->Status;\r
- }\r
-\r
- if (*Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
- PtReferenceAdapt(pAdapt);\r
-\r
-#pragma prefast(suppress: __WARNING_POTENTIAL_BUFFER_OVERFLOW, "Ndis guarantees MediumIndex to be within bounds");\r
- pAdapt->Medium = MediumArray[MediumIndex];\r
-\r
- //\r
- // Now ask NDIS to initialize our miniport (upper) edge.\r
- // Set the flag below to synchronize with a possible call\r
- // to our protocol Unbind handler that may come in before\r
- // our miniport initialization happens.\r
- //\r
- pAdapt->MiniportInitPending = TRUE;\r
- NdisInitializeEvent(&pAdapt->MiniportInitEvent);\r
-\r
- PtReferenceAdapt(pAdapt);\r
-\r
- *Status = NdisIMInitializeDeviceInstanceEx(DriverHandle,\r
- &pAdapt->DeviceName,\r
- pAdapt);\r
-\r
- if (*Status != NDIS_STATUS_SUCCESS)\r
- {\r
- if (pAdapt->MiniportIsHalted == TRUE)\r
- {\r
- NoCleanUpNeeded = TRUE;\r
- }\r
- \r
- DBGPRINT(("BindAdapter: Adapt %p, IMInitializeDeviceInstance error %x\n",\r
- pAdapt, *Status));\r
- \r
- if (PtDereferenceAdapt(pAdapt))\r
- {\r
- pAdapt = NULL;\r
- }\r
- \r
- break;\r
- }\r
- \r
- PtDereferenceAdapt(pAdapt);\r
-\r
- } while(FALSE);\r
-\r
- //\r
- // Close the configuration handle now - see comments above with\r
- // the call to NdisIMInitializeDeviceInstanceEx.\r
- //\r
- if (ConfigHandle != NULL)\r
- {\r
- NdisCloseConfiguration(ConfigHandle);\r
- }\r
-\r
- if ((*Status != NDIS_STATUS_SUCCESS) && (NoCleanUpNeeded == FALSE))\r
- {\r
- if (pAdapt != NULL)\r
- {\r
- if (pAdapt->BindingHandle != NULL)\r
- {\r
- NDIS_STATUS LocalStatus;\r
-\r
- //\r
- // Close the binding we opened above.\r
- //\r
-\r
- NdisResetEvent(&pAdapt->Event);\r
- \r
- NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle);\r
- pAdapt->BindingHandle = NULL;\r
-\r
- if (LocalStatus == NDIS_STATUS_PENDING)\r
- {\r
- NdisWaitEvent(&pAdapt->Event, 0);\r
- LocalStatus = pAdapt->Status;\r
-\r
- \r
- }\r
- if (PtDereferenceAdapt(pAdapt))\r
- {\r
- pAdapt = NULL;\r
- }\r
- }\r
- }\r
- }\r
-\r
-\r
- DBGPRINT(("<== Protocol BindAdapter: pAdapt %p, Status %x\n", pAdapt, *Status));\r
-}\r
-\r
-\r
-VOID\r
-PtOpenAdapterComplete(\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN NDIS_STATUS Status,\r
- IN NDIS_STATUS OpenErrorStatus\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Completion routine for NdisOpenAdapter issued from within the PtBindAdapter. Simply\r
- unblock the caller.\r
-\r
-Arguments:\r
-\r
- ProtocolBindingContext Pointer to the adapter\r
- Status Status of the NdisOpenAdapter call\r
- OpenErrorStatus Secondary status(ignored by us).\r
-\r
-Return Value:\r
-\r
- None\r
-\r
---*/\r
-{\r
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;\r
- \r
- UNREFERENCED_PARAMETER(OpenErrorStatus);\r
- \r
- DBGPRINT(("==> PtOpenAdapterComplete: Adapt %p, Status %x\n", pAdapt, Status));\r
- pAdapt->Status = Status;\r
- NdisSetEvent(&pAdapt->Event);\r
-}\r
-\r
-\r
-VOID\r
-PtUnbindAdapter(\r
- OUT PNDIS_STATUS Status,\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN NDIS_HANDLE UnbindContext\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Called by NDIS when we are required to unbind to the adapter below.\r
- This functions shares functionality with the miniport's HaltHandler.\r
- The code should ensure that NdisCloseAdapter and NdisFreeMemory is called\r
- only once between the two functions\r
-\r
-Arguments:\r
-\r
- Status Placeholder for return status\r
- ProtocolBindingContext Pointer to the adapter structure\r
- UnbindContext Context for NdisUnbindComplete() if this pends\r
-\r
-Return Value:\r
-\r
- Status for NdisIMDeinitializeDeviceContext\r
-\r
---*/\r
-{\r
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;\r
- NDIS_STATUS LocalStatus;\r
-\r
- UNREFERENCED_PARAMETER(UnbindContext);\r
- \r
- DBGPRINT(("==> PtUnbindAdapter: Adapt %p\n", pAdapt));\r
-\r
- //\r
- // Set the flag that the miniport below is unbinding, so the request handlers will\r
- // fail any request comming later\r
- // \r
- NdisAcquireSpinLock(&pAdapt->Lock);\r
- pAdapt->UnbindingInProcess = TRUE;\r
- if (pAdapt->QueuedRequest == TRUE)\r
- {\r
- pAdapt->QueuedRequest = FALSE;\r
- NdisReleaseSpinLock(&pAdapt->Lock);\r
-\r
- PtRequestComplete(pAdapt,\r
- &pAdapt->Request,\r
- NDIS_STATUS_FAILURE );\r
-\r
- }\r
- else\r
- {\r
- NdisReleaseSpinLock(&pAdapt->Lock);\r
- }\r
-#ifndef WIN9X\r
- //\r
- // Check if we had called NdisIMInitializeDeviceInstanceEx and\r
- // we are awaiting a call to MiniportInitialize.\r
- //\r
- if (pAdapt->MiniportInitPending == TRUE)\r
- {\r
- //\r
- // Try to cancel the pending IMInit process.\r
- //\r
- LocalStatus = NdisIMCancelInitializeDeviceInstance(\r
- DriverHandle,\r
- &pAdapt->DeviceName);\r
-\r
- if (LocalStatus == NDIS_STATUS_SUCCESS)\r
- {\r
- //\r
- // Successfully cancelled IM Initialization; our\r
- // Miniport Initialize routine will not be called\r
- // for this device.\r
- //\r
- pAdapt->MiniportInitPending = FALSE;\r
- ASSERT(pAdapt->MiniportHandle == NULL);\r
- }\r
- else\r
- {\r
- //\r
- // Our Miniport Initialize routine will be called\r
- // (may be running on another thread at this time).\r
- // Wait for it to finish.\r
- //\r
- NdisWaitEvent(&pAdapt->MiniportInitEvent, 0);\r
- ASSERT(pAdapt->MiniportInitPending == FALSE);\r
- }\r
-\r
- }\r
-#endif // !WIN9X\r
-\r
- //\r
- // Call NDIS to remove our device-instance. We do most of the work\r
- // inside the HaltHandler.\r
- //\r
- // The Handle will be NULL if our miniport Halt Handler has been called or\r
- // if the IM device was never initialized\r
- //\r
- \r
- if (pAdapt->MiniportHandle != NULL)\r
- {\r
- *Status = NdisIMDeInitializeDeviceInstance(pAdapt->MiniportHandle);\r
-\r
- if (*Status != NDIS_STATUS_SUCCESS)\r
- {\r
- *Status = NDIS_STATUS_FAILURE;\r
- }\r
- }\r
- else\r
- {\r
- //\r
- // We need to do some work here. \r
- // Close the binding below us \r
- // and release the memory allocated.\r
- //\r
- \r
- if(pAdapt->BindingHandle != NULL)\r
- {\r
- NdisResetEvent(&pAdapt->Event);\r
-\r
- NdisCloseAdapter(Status, pAdapt->BindingHandle);\r
-\r
- //\r
- // Wait for it to complete\r
- //\r
- if(*Status == NDIS_STATUS_PENDING)\r
- {\r
- NdisWaitEvent(&pAdapt->Event, 0);\r
- *Status = pAdapt->Status;\r
- }\r
- pAdapt->BindingHandle = NULL;\r
- }\r
- else\r
- {\r
- //\r
- // Both Our MiniportHandle and Binding Handle should not be NULL.\r
- //\r
- *Status = NDIS_STATUS_FAILURE;\r
- ASSERT(0);\r
- }\r
-\r
- //\r
- // Free the memory here, if was not released earlier(by calling the HaltHandler)\r
- //\r
- MPFreeAllPacketPools(pAdapt);\r
- NdisFreeSpinLock(&pAdapt->Lock);\r
- NdisFreeMemory(pAdapt, 0, 0);\r
- }\r
-\r
- DBGPRINT(("<== PtUnbindAdapter: Adapt %p\n", pAdapt));\r
-}\r
-\r
-VOID\r
-PtUnloadProtocol(\r
- VOID\r
-)\r
-{\r
- NDIS_STATUS Status;\r
-\r
- if (ProtHandle != NULL)\r
- {\r
- NdisDeregisterProtocol(&Status, ProtHandle);\r
- ProtHandle = NULL;\r
- }\r
-\r
- DBGPRINT(("PtUnloadProtocol: done!\n"));\r
-}\r
-\r
-\r
-\r
-VOID\r
-PtCloseAdapterComplete(\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN NDIS_STATUS Status\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Completion for the CloseAdapter call.\r
-\r
-Arguments:\r
-\r
- ProtocolBindingContext Pointer to the adapter structure\r
- Status Completion status\r
-\r
-Return Value:\r
-\r
- None.\r
-\r
---*/\r
-{\r
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;\r
-\r
- DBGPRINT(("CloseAdapterComplete: Adapt %p, Status %x\n", pAdapt, Status));\r
- pAdapt->Status = Status;\r
- NdisSetEvent(&pAdapt->Event);\r
-}\r
-\r
-\r
-VOID\r
-PtResetComplete(\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN NDIS_STATUS Status\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Completion for the reset.\r
-\r
-Arguments:\r
-\r
- ProtocolBindingContext Pointer to the adapter structure\r
- Status Completion status\r
-\r
-Return Value:\r
-\r
- None.\r
-\r
---*/\r
-{\r
-\r
- UNREFERENCED_PARAMETER(ProtocolBindingContext);\r
- UNREFERENCED_PARAMETER(Status);\r
- //\r
- // We never issue a reset, so we should not be here.\r
- //\r
- ASSERT(0);\r
-}\r
-\r
-\r
-VOID\r
-PtRequestComplete(\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN PNDIS_REQUEST NdisRequest,\r
- IN NDIS_STATUS Status\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Completion handler for the previously posted request. All OIDS\r
- are completed by and sent to the same miniport that they were requested for.\r
- If Oid == OID_PNP_QUERY_POWER then the data structure needs to returned with all entries =\r
- NdisDeviceStateUnspecified\r
-\r
-Arguments:\r
-\r
- ProtocolBindingContext Pointer to the adapter structure\r
- NdisRequest The posted request\r
- Status Completion status\r
-\r
-Return Value:\r
-\r
- None\r
-\r
---*/\r
-{\r
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;\r
- NDIS_OID Oid = pAdapt->Request.DATA.SET_INFORMATION.Oid ;\r
-\r
- //\r
- // Since our request is not outstanding anymore\r
- //\r
- ASSERT(pAdapt->OutstandingRequests == TRUE);\r
-\r
- pAdapt->OutstandingRequests = FALSE;\r
-\r
- //\r
- // Complete the Set or Query, and fill in the buffer for OID_PNP_CAPABILITIES, if need be.\r
- //\r
- switch (NdisRequest->RequestType)\r
- {\r
- case NdisRequestQueryInformation:\r
-\r
- //\r
- // We never pass OID_PNP_QUERY_POWER down.\r
- //\r
- ASSERT(Oid != OID_PNP_QUERY_POWER);\r
-\r
- if ((Oid == OID_PNP_CAPABILITIES) && (Status == NDIS_STATUS_SUCCESS))\r
- {\r
- MPQueryPNPCapabilities(pAdapt, &Status);\r
- }\r
- *pAdapt->BytesReadOrWritten = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;\r
- *pAdapt->BytesNeeded = NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;\r
-\r
- if (((Oid == OID_GEN_MAC_OPTIONS) \r
- && (Status == NDIS_STATUS_SUCCESS))\r
- && (NdisDotSysVersion >= NDIS_SYS_VERSION_51))\r
- {\r
- //\r
- // Only do this on Windows XP or greater (NDIS.SYS v 5.1); \r
- // do not do in Windows 2000 (NDIS.SYS v 5.0))\r
- //\r
- \r
- //\r
- // Remove the no-loopback bit from mac-options. In essence we are\r
- // telling NDIS that we can handle loopback. We don't, but the\r
- // interface below us does. If we do not do this, then loopback\r
- // processing happens both below us and above us. This is wasteful\r
- // at best and if Netmon is running, it will see multiple copies\r
- // of loopback packets when sniffing above us.\r
- //\r
- // Only the lowest miniport is a stack of layered miniports should\r
- // ever report this bit set to NDIS.\r
- //\r
- *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer &= ~NDIS_MAC_OPTION_NO_LOOPBACK;\r
- }\r
-\r
- NdisMQueryInformationComplete(pAdapt->MiniportHandle,\r
- Status);\r
- break;\r
-\r
- case NdisRequestSetInformation:\r
-\r
- ASSERT( Oid != OID_PNP_SET_POWER);\r
-\r
- *pAdapt->BytesReadOrWritten = NdisRequest->DATA.SET_INFORMATION.BytesRead;\r
- *pAdapt->BytesNeeded = NdisRequest->DATA.SET_INFORMATION.BytesNeeded;\r
- NdisMSetInformationComplete(pAdapt->MiniportHandle,\r
- Status);\r
- break;\r
-\r
- default:\r
- ASSERT(0);\r
- break;\r
- }\r
- \r
-}\r
-\r
-\r
-VOID\r
-PtStatus(\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN NDIS_STATUS GeneralStatus,\r
- IN PVOID StatusBuffer,\r
- IN UINT StatusBufferSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Status handler for the lower-edge(protocol).\r
-\r
-Arguments:\r
-\r
- ProtocolBindingContext Pointer to the adapter structure\r
- GeneralStatus Status code\r
- StatusBuffer Status buffer\r
- StatusBufferSize Size of the status buffer\r
-\r
-Return Value:\r
-\r
- None\r
-\r
---*/\r
-{\r
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;\r
-\r
- //\r
- // Pass up this indication only if the upper edge miniport is initialized\r
- // and powered on. Also ignore indications that might be sent by the lower\r
- // miniport when it isn't at D0.\r
- //\r
- if ((pAdapt->MiniportHandle != NULL) &&\r
- (pAdapt->MPDeviceState == NdisDeviceStateD0) &&\r
- (pAdapt->PTDeviceState == NdisDeviceStateD0)) \r
- {\r
- if ((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) || \r
- (GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT))\r
- {\r
- \r
- pAdapt->LastIndicatedStatus = GeneralStatus;\r
- }\r
- NdisMIndicateStatus(pAdapt->MiniportHandle,\r
- GeneralStatus,\r
- StatusBuffer,\r
- StatusBufferSize);\r
- }\r
- //\r
- // Save the last indicated media status \r
- //\r
- else\r
- {\r
- if ((pAdapt->MiniportHandle != NULL) && \r
- ((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) || \r
- (GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT)))\r
- {\r
- pAdapt->LatestUnIndicateStatus = GeneralStatus;\r
- }\r
- }\r
- \r
-}\r
-\r
-\r
-VOID\r
-PtStatusComplete(\r
- IN NDIS_HANDLE ProtocolBindingContext\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-\r
-Arguments:\r
-\r
-\r
-Return Value:\r
-\r
-\r
---*/\r
-{\r
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;\r
-\r
- //\r
- // Pass up this indication only if the upper edge miniport is initialized\r
- // and powered on. Also ignore indications that might be sent by the lower\r
- // miniport when it isn't at D0.\r
- //\r
- if ((pAdapt->MiniportHandle != NULL) &&\r
- (pAdapt->MPDeviceState == NdisDeviceStateD0) &&\r
- (pAdapt->PTDeviceState == NdisDeviceStateD0)) \r
- {\r
- NdisMIndicateStatusComplete(pAdapt->MiniportHandle);\r
- }\r
-}\r
-\r
-\r
-VOID\r
-PtSendComplete(\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN PNDIS_PACKET Packet,\r
- IN NDIS_STATUS Status\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Called by NDIS when the miniport below had completed a send. We should\r
- complete the corresponding upper-edge send this represents.\r
-\r
-Arguments:\r
-\r
- ProtocolBindingContext - Points to ADAPT structure\r
- Packet - Low level packet being completed\r
- Status - status of send\r
-\r
-Return Value:\r
-\r
- None\r
-\r
---*/\r
-{\r
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;\r
- PNDIS_PACKET Pkt; \r
- NDIS_HANDLE PoolHandle;\r
-\r
-#ifdef NDIS51\r
- //\r
- // Packet stacking:\r
- //\r
- // Determine if the packet we are completing is the one we allocated. If so, then\r
- // get the original packet from the reserved area and completed it and free the\r
- // allocated packet. If this is the packet that was sent down to us, then just\r
- // complete it\r
- //\r
- PoolHandle = NdisGetPoolFromPacket(Packet);\r
- if (PoolHandle != pAdapt->SendPacketPoolHandle)\r
- {\r
- //\r
- // We had passed down a packet belonging to the protocol above us.\r
- //\r
- // DBGPRINT(("PtSendComp: Adapt %p, Stacked Packet %p\n", pAdapt, Packet));\r
-\r
- NdisMSendComplete(pAdapt->MiniportHandle,\r
- Packet,\r
- Status);\r
- }\r
- else\r
-#endif // NDIS51\r
- {\r
- PSEND_RSVD SendRsvd;\r
-\r
- SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved);\r
- Pkt = SendRsvd->OriginalPkt;\r
- \r
-#ifndef WIN9X\r
- NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);\r
-#endif\r
- \r
- NdisDprFreePacket(Packet);\r
-\r
- NdisMSendComplete(pAdapt->MiniportHandle,\r
- Pkt,\r
- Status);\r
- }\r
- //\r
- // Decrease the outstanding send count\r
- //\r
- ADAPT_DECR_PENDING_SENDS(pAdapt);\r
-} \r
-\r
-\r
-VOID\r
-PtTransferDataComplete(\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN PNDIS_PACKET Packet,\r
- IN NDIS_STATUS Status,\r
- IN UINT BytesTransferred\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Entry point called by NDIS to indicate completion of a call by us\r
- to NdisTransferData.\r
-\r
- See notes under SendComplete.\r
-\r
-Arguments:\r
-\r
-Return Value:\r
-\r
---*/\r
-{\r
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;\r
-\r
- if(pAdapt->MiniportHandle)\r
- {\r
- NdisMTransferDataComplete(pAdapt->MiniportHandle,\r
- Packet,\r
- Status,\r
- BytesTransferred);\r
- }\r
-}\r
-\r
-\r
-NDIS_STATUS\r
-PtReceive(\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN NDIS_HANDLE MacReceiveContext,\r
- IN PVOID HeaderBuffer,\r
- IN UINT HeaderBufferSize,\r
- IN PVOID LookAheadBuffer,\r
- IN UINT LookAheadBufferSize,\r
- IN UINT PacketSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Handle receive data indicated up by the miniport below. We pass\r
- it along to the protocol above us.\r
-\r
- If the miniport below indicates packets, NDIS would more\r
- likely call us at our ReceivePacket handler. However we\r
- might be called here in certain situations even though\r
- the miniport below has indicated a receive packet, e.g.\r
- if the miniport had set packet status to NDIS_STATUS_RESOURCES.\r
- \r
-Arguments:\r
-\r
- <see DDK ref page for ProtocolReceive>\r
-\r
-Return Value:\r
-\r
- NDIS_STATUS_SUCCESS if we processed the receive successfully,\r
- NDIS_STATUS_XXX error code if we discarded it.\r
-\r
---*/\r
-{\r
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;\r
- PNDIS_PACKET MyPacket, Packet = NULL;\r
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;\r
- ULONG Proc = KeGetCurrentProcessorNumber(); \r
- \r
- if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0))\r
- {\r
- Status = NDIS_STATUS_FAILURE;\r
- }\r
- else do\r
- {\r
- //\r
- // Get at the packet, if any, indicated up by the miniport below.\r
- //\r
- Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);\r
- if (Packet != NULL)\r
- {\r
- //\r
- // The miniport below did indicate up a packet. Use information\r
- // from that packet to construct a new packet to indicate up.\r
- //\r
-\r
-#ifdef NDIS51\r
- //\r
- // NDIS 5.1 NOTE: Do not reuse the original packet in indicating\r
- // up a receive, even if there is sufficient packet stack space.\r
- // If we had to do so, we would have had to overwrite the\r
- // status field in the original packet to NDIS_STATUS_RESOURCES,\r
- // and it is not allowed for protocols to overwrite this field\r
- // in received packets.\r
- //\r
-#endif // NDIS51\r
-\r
- //\r
- // Get a packet off the pool and indicate that up\r
- //\r
- NdisDprAllocatePacket(&Status,\r
- &MyPacket,\r
- pAdapt->RecvPacketPoolHandle);\r
-\r
- if (Status == NDIS_STATUS_SUCCESS)\r
- {\r
- //\r
- // Make our packet point to data from the original\r
- // packet. NOTE: this works only because we are\r
- // indicating a receive directly from the context of\r
- // our receive indication. If we need to queue this\r
- // packet and indicate it from another thread context,\r
- // we will also have to allocate a new buffer and copy\r
- // over the packet contents, OOB data and per-packet\r
- // information. This is because the packet data\r
- // is available only for the duration of this\r
- // receive indication call.\r
- //\r
- NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);\r
- NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);\r
-\r
- //\r
- // Get the original packet (it could be the same packet as the\r
- // one received or a different one based on the number of layered\r
- // miniports below) and set it on the indicated packet so the OOB\r
- // data is visible correctly at protocols above. If the IM driver \r
- // modifies the packet in any way it should not set the new packet's\r
- // original packet equal to the original packet of the packet that \r
- // was indicated to it from the underlying driver, in this case, the \r
- // IM driver should also ensure that the related per packet info should\r
- // be copied to the new packet.\r
- // we can set the original packet to the original packet of the packet\r
- // indicated from the underlying driver because the driver doesn't modify\r
- // the data content in the packet.\r
- //\r
- NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));\r
- NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);\r
-\r
- //\r
- // Copy packet flags.\r
- //\r
- NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);\r
-\r
- //\r
- // Force protocols above to make a copy if they want to hang\r
- // on to data in this packet. This is because we are in our\r
- // Receive handler (not ReceivePacket) and we can't return a\r
- // ref count from here.\r
- //\r
- NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES);\r
-\r
- //\r
- // By setting NDIS_STATUS_RESOURCES, we also know that we can reclaim\r
- // this packet as soon as the call to NdisMIndicateReceivePacket\r
- // returns.\r
- //\r
-\r
- if (pAdapt->MiniportHandle != NULL)\r
- {\r
- NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);\r
- }\r
-\r
- //\r
- // Reclaim the indicated packet. Since we had set its status\r
- // to NDIS_STATUS_RESOURCES, we are guaranteed that protocols\r
- // above are done with it.\r
- //\r
- NdisDprFreePacket(MyPacket);\r
-\r
- break;\r
- }\r
- }\r
- else\r
- {\r
- //\r
- // The miniport below us uses the old-style (not packet)\r
- // receive indication. Fall through.\r
- //\r
- }\r
-\r
- //\r
- // Fall through if the miniport below us has either not\r
- // indicated a packet or we could not allocate one\r
- //\r
- pAdapt->ReceivedIndicationFlags[Proc] = TRUE;\r
- if (pAdapt->MiniportHandle == NULL)\r
- {\r
- break;\r
- }\r
- switch (pAdapt->Medium)\r
- {\r
- case NdisMedium802_3:\r
- case NdisMediumWan:\r
- NdisMEthIndicateReceive(pAdapt->MiniportHandle,\r
- MacReceiveContext,\r
- HeaderBuffer,\r
- HeaderBufferSize,\r
- LookAheadBuffer,\r
- LookAheadBufferSize,\r
- PacketSize);\r
- break;\r
-\r
- case NdisMedium802_5:\r
- NdisMTrIndicateReceive(pAdapt->MiniportHandle,\r
- MacReceiveContext,\r
- HeaderBuffer,\r
- HeaderBufferSize,\r
- LookAheadBuffer,\r
- LookAheadBufferSize,\r
- PacketSize);\r
- break;\r
-\r
-#if FDDI\r
- case NdisMediumFddi:\r
- NdisMFddiIndicateReceive(pAdapt->MiniportHandle,\r
- MacReceiveContext,\r
- HeaderBuffer,\r
- HeaderBufferSize,\r
- LookAheadBuffer,\r
- LookAheadBufferSize,\r
- PacketSize);\r
- break;\r
-#endif\r
- default:\r
- ASSERT(FALSE);\r
- break;\r
- }\r
-\r
- } while(FALSE);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-VOID\r
-PtReceiveComplete(\r
- IN NDIS_HANDLE ProtocolBindingContext\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Called by the adapter below us when it is done indicating a batch of\r
- received packets.\r
-\r
-Arguments:\r
-\r
- ProtocolBindingContext Pointer to our adapter structure.\r
-\r
-Return Value:\r
-\r
- None\r
-\r
---*/\r
-{\r
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;\r
- ULONG Proc = KeGetCurrentProcessorNumber(); \r
-\r
- if (((pAdapt->MiniportHandle != NULL)\r
- && (pAdapt->MPDeviceState == NdisDeviceStateD0))\r
- && (pAdapt->ReceivedIndicationFlags[Proc]))\r
- {\r
- switch (pAdapt->Medium)\r
- {\r
- case NdisMedium802_3:\r
- case NdisMediumWan:\r
- NdisMEthIndicateReceiveComplete(pAdapt->MiniportHandle);\r
- break;\r
-\r
- case NdisMedium802_5:\r
- NdisMTrIndicateReceiveComplete(pAdapt->MiniportHandle);\r
- break;\r
-#if FDDI\r
- case NdisMediumFddi:\r
- NdisMFddiIndicateReceiveComplete(pAdapt->MiniportHandle);\r
- break;\r
-#endif\r
- default:\r
- ASSERT(FALSE);\r
- break;\r
- }\r
- }\r
-\r
- pAdapt->ReceivedIndicationFlags[Proc] = FALSE;\r
-}\r
-\r
-\r
-INT\r
-PtReceivePacket(\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN PNDIS_PACKET Packet\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- ReceivePacket handler. Called by NDIS if the miniport below supports\r
- NDIS 4.0 style receives. Re-package the buffer chain in a new packet\r
- and indicate the new packet to protocols above us. Any context for\r
- packets indicated up must be kept in the MiniportReserved field.\r
-\r
- NDIS 5.1 - packet stacking - if there is sufficient "stack space" in\r
- the packet passed to us, we can use the same packet in a receive\r
- indication.\r
-\r
-Arguments:\r
-\r
- ProtocolBindingContext - Pointer to our adapter structure.\r
- Packet - Pointer to the packet\r
-\r
-Return Value:\r
-\r
- == 0 -> We are done with the packet\r
- != 0 -> We will keep the packet and call NdisReturnPackets() this\r
- many times when done.\r
---*/\r
-{\r
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;\r
- NDIS_STATUS Status;\r
- PNDIS_PACKET MyPacket;\r
- BOOLEAN Remaining;\r
-\r
- //\r
- // Drop the packet silently if the upper miniport edge isn't initialized or\r
- // the miniport edge is in low power state\r
- //\r
- if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0))\r
- {\r
- return 0;\r
- }\r
-\r
-#ifdef NDIS51\r
- //\r
- // Check if we can reuse the same packet for indicating up.\r
- // See also: PtReceive(). \r
- //\r
- (VOID)NdisIMGetCurrentPacketStack(Packet, &Remaining);\r
- if (Remaining)\r
- {\r
- //\r
- // We can reuse "Packet". Indicate it up and be done with it.\r
- //\r
- Status = NDIS_GET_PACKET_STATUS(Packet);\r
- NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1);\r
- return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);\r
- }\r
-#endif // NDIS51\r
-\r
- //\r
- // Get a packet off the pool and indicate that up\r
- //\r
- NdisDprAllocatePacket(&Status,\r
- &MyPacket,\r
- pAdapt->RecvPacketPoolHandle);\r
-\r
- if (Status == NDIS_STATUS_SUCCESS)\r
- {\r
- PRECV_RSVD RecvRsvd;\r
-\r
- RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved);\r
- RecvRsvd->OriginalPkt = Packet;\r
-\r
- NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);\r
- NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);\r
-\r
- //\r
- // Get the original packet (it could be the same packet as the one\r
- // received or a different one based on the number of layered miniports\r
- // below) and set it on the indicated packet so the OOB data is visible\r
- // correctly to protocols above us.\r
- //\r
- NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));\r
-\r
- //\r
- // Set Packet Flags\r
- //\r
- NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);\r
-\r
- Status = NDIS_GET_PACKET_STATUS(Packet);\r
-\r
- NDIS_SET_PACKET_STATUS(MyPacket, Status);\r
- NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));\r
-\r
- if (pAdapt->MiniportHandle != NULL)\r
- {\r
- NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);\r
- }\r
-\r
- //\r
- // Check if we had indicated up the packet with NDIS_STATUS_RESOURCES\r
- // NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since\r
- // it might have changed! Use the value saved in the local variable.\r
- //\r
- if (Status == NDIS_STATUS_RESOURCES)\r
- {\r
- //\r
- // Our ReturnPackets handler will not be called for this packet.\r
- // We should reclaim it right here.\r
- //\r
- NdisDprFreePacket(MyPacket);\r
- }\r
-\r
- return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);\r
- }\r
- else\r
- {\r
- //\r
- // We are out of packets. Silently drop it.\r
- //\r
- return(0);\r
- }\r
-}\r
-\r
-\r
-NDIS_STATUS\r
-PtPNPHandler(\r
- IN NDIS_HANDLE ProtocolBindingContext,\r
- IN PNET_PNP_EVENT pNetPnPEvent\r
- )\r
-\r
-/*++\r
-Routine Description:\r
-\r
- This is called by NDIS to notify us of a PNP event related to a lower\r
- binding. Based on the event, this dispatches to other helper routines.\r
-\r
- NDIS 5.1: forward this event to the upper protocol(s) by calling\r
- NdisIMNotifyPnPEvent.\r
-\r
-Arguments:\r
-\r
- ProtocolBindingContext - Pointer to our adapter structure. Can be NULL\r
- for "global" notifications\r
-\r
- pNetPnPEvent - Pointer to the PNP event to be processed.\r
-\r
-Return Value:\r
-\r
- NDIS_STATUS code indicating status of event processing.\r
-\r
---*/\r
-{\r
- PADAPT pAdapt =(PADAPT)ProtocolBindingContext;\r
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;\r
-\r
- DBGPRINT(("PtPnPHandler: Adapt %p, Event %d\n", pAdapt, pNetPnPEvent->NetEvent));\r
-\r
- switch (pNetPnPEvent->NetEvent)\r
- {\r
- case NetEventSetPower:\r
- Status = PtPnPNetEventSetPower(pAdapt, pNetPnPEvent);\r
- break;\r
-\r
- case NetEventReconfigure:\r
- Status = PtPnPNetEventReconfigure(pAdapt, pNetPnPEvent);\r
- break;\r
-\r
- default:\r
-#ifdef NDIS51\r
- //\r
- // Pass on this notification to protocol(s) above, before\r
- // doing anything else with it.\r
- //\r
- if (pAdapt && pAdapt->MiniportHandle)\r
- {\r
- Status = NdisIMNotifyPnPEvent(pAdapt->MiniportHandle, pNetPnPEvent);\r
- }\r
-#else\r
- Status = NDIS_STATUS_SUCCESS;\r
-\r
-#endif // NDIS51\r
-\r
- break;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-NDIS_STATUS\r
-PtPnPNetEventReconfigure(\r
- IN PADAPT pAdapt,\r
- IN PNET_PNP_EVENT pNetPnPEvent\r
- )\r
-/*++\r
-Routine Description:\r
-\r
- This routine is called from NDIS to notify our protocol edge of a\r
- reconfiguration of parameters for either a specific binding (pAdapt\r
- is not NULL), or global parameters if any (pAdapt is NULL).\r
-\r
-Arguments:\r
-\r
- pAdapt - Pointer to our adapter structure.\r
- pNetPnPEvent - the reconfigure event\r
-\r
-Return Value:\r
-\r
- NDIS_STATUS_SUCCESS\r
-\r
---*/\r
-{\r
- NDIS_STATUS ReconfigStatus = NDIS_STATUS_SUCCESS;\r
- NDIS_STATUS ReturnStatus = NDIS_STATUS_SUCCESS;\r
-\r
- do\r
- {\r
- //\r
- // Is this is a global reconfiguration notification ?\r
- //\r
- if (pAdapt == NULL)\r
- {\r
- //\r
- // An important event that causes this notification to us is if\r
- // one of our upper-edge miniport instances was enabled after being\r
- // disabled earlier, e.g. from Device Manager in Win2000. Note that\r
- // NDIS calls this because we had set up an association between our\r
- // miniport and protocol entities by calling NdisIMAssociateMiniport.\r
- //\r
- // Since we would have torn down the lower binding for that miniport,\r
- // we need NDIS' assistance to re-bind to the lower miniport. The\r
- // call to NdisReEnumerateProtocolBindings does exactly that.\r
- //\r
- NdisReEnumerateProtocolBindings (ProtHandle); \r
- \r
- break;\r
- }\r
-\r
-#ifdef NDIS51\r
- //\r
- // Pass on this notification to protocol(s) above before doing anything\r
- // with it.\r
- //\r
- if (pAdapt->MiniportHandle)\r
- {\r
- ReturnStatus = NdisIMNotifyPnPEvent(pAdapt->MiniportHandle, pNetPnPEvent);\r
- }\r
-#endif // NDIS51\r
-\r
- ReconfigStatus = NDIS_STATUS_SUCCESS;\r
-\r
- } while(FALSE);\r
-\r
- DBGPRINT(("<==PtPNPNetEventReconfigure: pAdapt %p\n", pAdapt));\r
-\r
-#ifdef NDIS51\r
- //\r
- // Overwrite status with what upper-layer protocol(s) returned.\r
- //\r
- ReconfigStatus = ReturnStatus;\r
-#endif\r
-\r
- return ReconfigStatus;\r
-}\r
-\r
-\r
-NDIS_STATUS\r
-PtPnPNetEventSetPower(\r
- IN PADAPT pAdapt,\r
- IN PNET_PNP_EVENT pNetPnPEvent\r
- )\r
-/*++\r
-Routine Description:\r
-\r
- This is a notification to our protocol edge of the power state\r
- of the lower miniport. If it is going to a low-power state, we must\r
- wait here for all outstanding sends and requests to complete.\r
-\r
- NDIS 5.1: Since we use packet stacking, it is not sufficient to\r
- check usage of our local send packet pool to detect whether or not\r
- all outstanding sends have completed. For this, use the new API\r
- NdisQueryPendingIOCount.\r
-\r
- NDIS 5.1: Use the 5.1 API NdisIMNotifyPnPEvent to pass on PnP\r
- notifications to upper protocol(s).\r
-\r
-Arguments:\r
-\r
- pAdapt - Pointer to the adpater structure\r
- pNetPnPEvent - The Net Pnp Event. this contains the new device state\r
-\r
-Return Value:\r
-\r
- NDIS_STATUS_SUCCESS or the status returned by upper-layer protocols.\r
-\r
---*/\r
-{\r
- PNDIS_DEVICE_POWER_STATE pDeviceState =(PNDIS_DEVICE_POWER_STATE)(pNetPnPEvent->Buffer);\r
- NDIS_DEVICE_POWER_STATE PrevDeviceState = pAdapt->PTDeviceState; \r
- NDIS_STATUS Status;\r
- NDIS_STATUS ReturnStatus;\r
-\r
- ReturnStatus = NDIS_STATUS_SUCCESS;\r
-\r
- //\r
- // Set the Internal Device State, this blocks all new sends or receives\r
- //\r
- NdisAcquireSpinLock(&pAdapt->Lock);\r
- pAdapt->PTDeviceState = *pDeviceState;\r
-\r
- //\r
- // Check if the miniport below is going to a low power state.\r
- //\r
- if (pAdapt->PTDeviceState > NdisDeviceStateD0)\r
- {\r
- //\r
- // If the miniport below is going to standby, fail all incoming requests\r
- //\r
- if (PrevDeviceState == NdisDeviceStateD0)\r
- {\r
- pAdapt->StandingBy = TRUE;\r
- }\r
-\r
- NdisReleaseSpinLock(&pAdapt->Lock);\r
-\r
-#ifdef NDIS51\r
- //\r
- // Notify upper layer protocol(s) first.\r
- //\r
- if (pAdapt->MiniportHandle != NULL)\r
- {\r
- ReturnStatus = NdisIMNotifyPnPEvent(pAdapt->MiniportHandle, pNetPnPEvent);\r
- }\r
-#endif // NDIS51\r
-\r
- //\r
- // Wait for outstanding sends and requests to complete.\r
- //\r
- while (pAdapt->OutstandingSends != 0)\r
- {\r
- NdisMSleep(2);\r
- }\r
-\r
- while (pAdapt->OutstandingRequests == TRUE)\r
- {\r
- //\r
- // sleep till outstanding requests complete\r
- //\r
- NdisMSleep(2);\r
- }\r
-\r
- //\r
- // If the below miniport is going to low power state, complete the queued request\r
- //\r
- NdisAcquireSpinLock(&pAdapt->Lock);\r
- if (pAdapt->QueuedRequest)\r
- {\r
- pAdapt->QueuedRequest = FALSE;\r
- NdisReleaseSpinLock(&pAdapt->Lock);\r
- PtRequestComplete(pAdapt, &pAdapt->Request, NDIS_STATUS_FAILURE);\r
- }\r
- else\r
- {\r
- NdisReleaseSpinLock(&pAdapt->Lock);\r
- }\r
- \r
-\r
- ASSERT(NdisPacketPoolUsage(pAdapt->SendPacketPoolHandle) == 0);\r
- ASSERT(pAdapt->OutstandingRequests == FALSE);\r
- }\r
- else\r
- {\r
- //\r
- // If the physical miniport is powering up (from Low power state to D0), \r
- // clear the flag\r
- //\r
- if (PrevDeviceState > NdisDeviceStateD0)\r
- {\r
- pAdapt->StandingBy = FALSE;\r
- }\r
- //\r
- // The device below is being turned on. If we had a request\r
- // pending, send it down now.\r
- //\r
- if (pAdapt->QueuedRequest == TRUE)\r
- {\r
- pAdapt->QueuedRequest = FALSE;\r
- \r
- pAdapt->OutstandingRequests = TRUE;\r
- NdisReleaseSpinLock(&pAdapt->Lock);\r
-\r
- NdisRequest(&Status,\r
- pAdapt->BindingHandle,\r
- &pAdapt->Request);\r
-\r
- if (Status != NDIS_STATUS_PENDING)\r
- {\r
- PtRequestComplete(pAdapt,\r
- &pAdapt->Request,\r
- Status);\r
- \r
- }\r
- }\r
- else\r
- {\r
- NdisReleaseSpinLock(&pAdapt->Lock);\r
- }\r
-\r
-\r
-#ifdef NDIS51\r
- //\r
- // Pass on this notification to protocol(s) above\r
- //\r
- if (pAdapt->MiniportHandle)\r
- {\r
- ReturnStatus = NdisIMNotifyPnPEvent(pAdapt->MiniportHandle, pNetPnPEvent);\r
- }\r
-#endif // NDIS51\r
-\r
- }\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-VOID\r
-PtReferenceAdapt(\r
- IN PADAPT pAdapt\r
- )\r
-{\r
- NdisAcquireSpinLock(&pAdapt->Lock);\r
- \r
- ASSERT(pAdapt->RefCount >= 0);\r
-\r
- pAdapt->RefCount ++;\r
- NdisReleaseSpinLock(&pAdapt->Lock);\r
-}\r
-\r
-\r
-BOOLEAN\r
-PtDereferenceAdapt(\r
- IN PADAPT pAdapt\r
- )\r
-{\r
- NdisAcquireSpinLock(&pAdapt->Lock);\r
-\r
- ASSERT(pAdapt->RefCount > 0);\r
-\r
- pAdapt->RefCount--;\r
-\r
- if (pAdapt->RefCount == 0)\r
- {\r
- NdisReleaseSpinLock(&pAdapt->Lock);\r
- \r
- //\r
- // Free all resources on this adapter structure.\r
- //\r
- MPFreeAllPacketPools (pAdapt);;\r
- NdisFreeSpinLock(&pAdapt->Lock);\r
- NdisFreeMemory(pAdapt, 0 , 0);\r
- \r
- return TRUE;\r
- \r
- }\r
- else\r
- {\r
- NdisReleaseSpinLock(&pAdapt->Lock);\r
-\r
- return FALSE;\r
- }\r
-}\r
-\r
-\r