📄 miniport.c
字号:
pStatus - Place to return final status
Return Value:
None.
--*/
{
PNDIS_PNP_CAPABILITIES pPNPCapabilities;
PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct;
if (pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof(NDIS_PNP_CAPABILITIES))
{
pPNPCapabilities = (PNDIS_PNP_CAPABILITIES)(pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer);
//
// The following fields must be overwritten by an IM driver.
//
pPMstruct= & pPNPCapabilities->WakeUpCapabilities;
pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified;
pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
*pAdapt->BytesReadOrWritten = sizeof(NDIS_PNP_CAPABILITIES);
*pAdapt->BytesNeeded = 0;
//
// Setting our internal flags
// Default, device is ON
//
pAdapt->MPDeviceState = NdisDeviceStateD0;
pAdapt->PTDeviceState = NdisDeviceStateD0;
*pStatus = NDIS_STATUS_SUCCESS;
}
else
{
*pAdapt->BytesNeeded= sizeof(NDIS_PNP_CAPABILITIES);
*pStatus = NDIS_STATUS_RESOURCES;
}
}
NDIS_STATUS
MPSetInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
/*++
Routine Description:
Miniport SetInfo handler.
In the case of OID_PNP_SET_POWER, record the power state and return the OID.
Do not pass below
If the device is suspended, do not block the SET_POWER_OID
as it is used to reactivate the Passthru miniport
PM- If the MP is not ON (DeviceState > D0) return immediately (except for 'query power' and 'set power')
If MP is ON, but the PT is not at D0, then queue the queue the request for later processing
Requests to miniports are always serialized
Arguments:
MiniportAdapterContext Pointer to the adapter structure
Oid Oid for this query
InformationBuffer Buffer for information
InformationBufferLength Size of this buffer
BytesRead Specifies how much info is read
BytesNeeded In case the buffer is smaller than what we need, tell them how much is needed
Return Value:
Return code from the NdisRequest below.
--*/
{
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
NDIS_STATUS Status;
Status = NDIS_STATUS_FAILURE;
do
{
//
// The Set Power should not be sent to the miniport below the Passthru, but is handled internally
//
if (Oid == OID_PNP_SET_POWER)
{
MPProcessSetPowerOid(&Status,
pAdapt,
InformationBuffer,
InformationBufferLength,
BytesRead,
BytesNeeded);
break;
}
//
// If the miniport below is unbinding, fail the request
//
NdisAcquireSpinLock(&pAdapt->Lock);
if (pAdapt->UnbindingInProcess == TRUE)
{
NdisReleaseSpinLock(&pAdapt->Lock);
Status = NDIS_STATUS_FAILURE;
break;
}
NdisReleaseSpinLock(&pAdapt->Lock);
//
// All other Set Information requests are failed, if the miniport is
// not at D0 or is transitioning to a device state greater than D0.
//
if (pAdapt->MPDeviceState > NdisDeviceStateD0)
{
Status = NDIS_STATUS_FAILURE;
break;
}
if (OID_CUSTOM_ARRAY==Oid) // Set custom array? ja, 28.09.2003.
{
// The input data are a 4-byte word given the number of elements, followed by
// that number of 4-byte elements.
PPassthruIPAddrArray pInArr = // Point to incoming buffer.
(PPassthruIPAddrArray)InformationBuffer;
NDIS_STATUS lclStatus;
// DBGPRINT(("MPSetInformation(): For adapter at 0x%08x, Oid = OID_CUSTOM_ARRAY\n",
// pAdapt));
lclStatus =
PassthruWMISetAddrArray(
pAdapt,
pInArr->NumberElements,
pInArr
);
if (NDIS_STATUS_SUCCESS!=lclStatus)
{
DBGPRINT(("MPSetInformation(): Failed in PassthruWMISetAddrArray(), status 0x%08x!\n", lclStatus));
Status = lclStatus;
*BytesRead = 0;
*BytesNeeded = 0;
break;
}
*BytesRead = InformationBufferLength;
Status = NDIS_STATUS_SUCCESS;
break;
}
// Set up the Request and return the result
pAdapt->Request.RequestType = NdisRequestSetInformation;
pAdapt->Request.DATA.SET_INFORMATION.Oid = Oid;
pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
pAdapt->Request.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;
pAdapt->BytesNeeded = BytesNeeded;
pAdapt->BytesReadOrWritten = BytesRead;
//
// If the miniport below is unbinding, fail the request
//
NdisAcquireSpinLock(&pAdapt->Lock);
if (pAdapt->UnbindingInProcess == TRUE)
{
NdisReleaseSpinLock(&pAdapt->Lock);
Status = NDIS_STATUS_FAILURE;
break;
}
//
// If the device below is at a low power state, we cannot send it the
// request now, and must pend it.
//
if ((pAdapt->PTDeviceState > NdisDeviceStateD0)
&& (pAdapt->StandingBy == FALSE))
{
pAdapt->QueuedRequest = TRUE;
NdisReleaseSpinLock(&pAdapt->Lock);
Status = NDIS_STATUS_PENDING;
break;
}
//
// This is in the process of powering down the system, always fail the request
//
if (pAdapt->StandingBy == TRUE)
{
NdisReleaseSpinLock(&pAdapt->Lock);
Status = NDIS_STATUS_FAILURE;
break;
}
pAdapt->OutstandingRequests = TRUE;
NdisReleaseSpinLock(&pAdapt->Lock);
//
// Forward the request to the device below.
//
NdisRequest(&Status,
pAdapt->BindingHandle,
&pAdapt->Request);
if (Status != NDIS_STATUS_PENDING)
{
*BytesRead = pAdapt->Request.DATA.SET_INFORMATION.BytesRead;
*BytesNeeded = pAdapt->Request.DATA.SET_INFORMATION.BytesNeeded;
pAdapt->OutstandingRequests = FALSE;
}
} while (FALSE);
return(Status);
}
VOID
MPProcessSetPowerOid(
IN OUT PNDIS_STATUS pNdisStatus,
IN PADAPT pAdapt,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
/*++
Routine Description:
This routine does all the procssing for a request with a SetPower Oid
The miniport shoud accept the Set Power and transition to the new state
The Set Power should not be passed to the miniport below
If the IM miniport is going into a low power state, then there is no guarantee if it will ever
be asked go back to D0, before getting halted. No requests should be pended or queued.
Arguments:
pNdisStatus - Status of the operation
pAdapt - The Adapter structure
InformationBuffer - The New DeviceState
InformationBufferLength
BytesRead - No of bytes read
BytesNeeded - No of bytes needed
Return Value:
Status - NDIS_STATUS_SUCCESS if all the wait events succeed.
--*/
{
NDIS_DEVICE_POWER_STATE NewDeviceState;
DBGPRINT(("==>MPProcessSetPowerOid: Adapt %p\n", pAdapt));
ASSERT (InformationBuffer != NULL);
*pNdisStatus = NDIS_STATUS_FAILURE;
do
{
//
// Check for invalid length
//
if (InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE))
{
*pNdisStatus = NDIS_STATUS_INVALID_LENGTH;
break;
}
NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer);
//
// Check for invalid device state
//
if ((pAdapt->MPDeviceState > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0))
{
//
// If the miniport is in a non-D0 state, the miniport can only receive a Set Power to D0
//
ASSERT (!(pAdapt->MPDeviceState > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0));
*pNdisStatus = NDIS_STATUS_FAILURE;
break;
}
//
// Is the miniport transitioning from an On (D0) state to an Low Power State (>D0)
// If so, then set the StandingBy Flag - (Block all incoming requests)
//
if (pAdapt->MPDeviceState == NdisDeviceStateD0 && NewDeviceState > NdisDeviceStateD0)
{
pAdapt->StandingBy = TRUE;
}
//
// If the miniport is transitioning from a low power state to ON (D0), then clear the StandingBy flag
// All incoming requests will be pended until the physical miniport turns ON.
//
if (pAdapt->MPDeviceState > NdisDeviceStateD0 && NewDeviceState == NdisDeviceStateD0)
{
pAdapt->StandingBy = FALSE;
}
//
// Now update the state in the pAdapt structure;
//
pAdapt->MPDeviceState = NewDeviceState;
*pNdisStatus = NDIS_STATUS_SUCCESS;
} while (FALSE);
if (*pNdisStatus == NDIS_STATUS_SUCCESS)
{
//
// The miniport resume from low power state
//
if (pAdapt->StandingBy == FALSE)
{
//
// If we need to indicate the media connect state
//
if (pAdapt->LastIndicatedStatus != pAdapt->LatestUnIndicateStatus)
{
NdisMIndicateStatus(pAdapt->MiniportHandle,
pAdapt->LatestUnIndicateStatus,
(PVOID)NULL,
0);
NdisMIndicateStatusComplete(pAdapt->MiniportHandle);
pAdapt->LastIndicatedStatus = pAdapt->LatestUnIndicateStatus;
}
}
else
{
//
// Initialize LatestUnIndicatedStatus
//
pAdapt->LatestUnIndicateStatus = pAdapt->LastIndicatedStatus;
}
*BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
*BytesNeeded = 0;
}
else
{
*BytesRead = 0;
*BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -