?? miniport.c
字號:
/*++
Routine Description:
Miniport QueryInfo handler.
In the Power Management scenario, OID_PNP_QUERY_POWER is not sent to the underlying miniport.
OID_PNP_CAPABILITES is passed as a request to the miniport below.
If the result is a success then the InformationBuffer is filled in the MPQueryPNPCapabilites.
LBFO - For present all queries are passed on to the miniports that they were requested on.
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
BytesWritten Specifies how much info is written
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 = NDIS_STATUS_FAILURE;
DbgPrint("QueryInformation");
do
{
//
// Return Success for this OID
//
if (Oid == OID_PNP_QUERY_POWER)
{
Status=NDIS_STATUS_SUCCESS;
break;
}
//
// All other queries are failed, if the miniport is not at D0
//
if (pAdapt->MPDeviceState > NdisDeviceStateD0 || pAdapt->StandingBy == TRUE)
{
Status = NDIS_STATUS_FAILURE;
break;
}
//
// We are doing all sends on the secondary, so send all requests with Send OIDs to the Secondary
//
if (MPIsSendOID(Oid))
{
pAdapt = pAdapt->pSecondaryAdapt;
//
// Will point to itself, if there is no secondary (see initialization)
//
}
pAdapt->Request.RequestType = NdisRequestQueryInformation;
pAdapt->Request.DATA.QUERY_INFORMATION.Oid = Oid;
pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;
pAdapt->BytesNeeded = BytesNeeded;
pAdapt->BytesReadOrWritten = BytesWritten;
pAdapt->OutstandingRequests = TRUE;
//
// if the Protocol device state is OFF, then the IM driver cannot send the request below and must pend it
//
if (pAdapt->PTDeviceState > NdisDeviceStateD0)
{
pAdapt->QueuedRequest = TRUE;
Status = NDIS_STATUS_PENDING;
break;
}
//
// default case, most requests will be passed to the miniport below
//
NdisRequest(&Status,
pAdapt->BindingHandle,
&pAdapt->Request);
//
// If the Query was a success, pass the results back to the entity that made the request
//
if (Status == NDIS_STATUS_SUCCESS)
{
*BytesWritten = pAdapt->Request.DATA.QUERY_INFORMATION.BytesWritten;
*BytesNeeded = pAdapt->Request.DATA.QUERY_INFORMATION.BytesNeeded;
}
//
// Fill the buffer with the required values if Oid == OID_PNP_CAPABILITIES
// and the query was successful
//
if (Oid == OID_PNP_CAPABILITIES && Status == NDIS_STATUS_SUCCESS)
{
MPQueryPNPCapbilities(pAdapt,&Status);
}
if (Status != NDIS_STATUS_PENDING)
{
pAdapt->OutstandingRequests = FALSE;
}
} while (FALSE);
return(Status);
}
VOID
MPQueryPNPCapbilities(
IN OUT PADAPT pAdapt,
OUT PNDIS_STATUS pStatus
)
/*++
Routine Description:
Miniport QueryInfo OID_PNP_CAPAIBILITIES:
If the Oid == Oid_PNP_CAPABILITIES, InformationBuffer is returned with all the fields
assigned NdisDeviceStateUnspecified in the NDIS_PM_WAKE_UP_CAPABILITIES structure
OID_QUERY_POWER_STATE is returned with NDIS_STATUS_SUCCESS and should never be passed below.
Arguments:
MiniportAdapterContext Pointer to the adapter structure
Oid Oid for this query
InformationBuffer Buffer for information
InformationBufferLength Size of this buffer
BytesWritten Specifies how much info is written
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.
--*/
{
PNDIS_PNP_CAPABILITIES pPNPCapabilities;
PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct;
DbgPrint("Mp Query Information\n");
if (pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof(NDIS_PNP_CAPABILITIES))
{
pPNPCapabilities = (PNDIS_PNP_CAPABILITIES)(pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer);
//
// Setting up the buffer to be returned to the Protocol above the Passthru miniport
//
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;
DbgPrint("MP Set Information\n");
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;
}
//
// 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 || pAdapt->StandingBy == TRUE)
{
Status = NDIS_STATUS_FAILURE;
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;
pAdapt->OutstandingRequests = TRUE;
//
// if the Protocol device state is OFF, then the IM driver cannot send the request below and must pend it
//
if ( pAdapt->PTDeviceState > NdisDeviceStateD0)
{
pAdapt->QueuedRequest = TRUE;
Status = NDIS_STATUS_PENDING;
break;
}
NdisRequest(&Status,
pAdapt->BindingHandle,
&pAdapt->Request);
if (Status == NDIS_STATUS_SUCCESS)
{
*BytesRead = pAdapt->Request.DATA.SET_INFORMATION.BytesRead;
*BytesNeeded = pAdapt->Request.DATA.SET_INFORMATION.BytesNeeded;
}
if (Status != NDIS_STATUS_PENDING)
{
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 SampleIM 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:
IN OUT PNDIS_STATUS *pNdisStatus - Status of the operation
IN PADAPT pAdapt, - The Adapter structure
IN PVOID InformationBuffer, - The New DeviceState
IN ULONG InformationBufferLength,
OUT PULONG BytesRead, - No of bytes read
OUT PULONG BytesNeeded - No of bytes needed
Return Value:
Status - NDIS_STATUS_SUCCESS if all the wait events succeed.
--*/
{
NDIS_DEVICE_POWER_STATE NewDeviceState;
//DBGPRINT ("==>MPProcessSetPowerOid");
ASSERT (InformationBuffer != NULL);
NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer);
*pNdisStatus = NDIS_STATUS_FAILURE;
do
{
//
// Check for invalid length
//
if (InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE))
{
*pNdisStatus = NDIS_STATUS_INVALID_LENGTH;
break;
}
//
// 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)
{
*BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
*BytesNeeded = 0;
}
else
{
*BytesRead = 0;
*BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
}
// DBGPRINT ("<==MPProcessSetPowerOid");
}
VOID
MPReturnPacket(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
PNDIS_PACKET MyPacket;
PRSVD Resvd;
// DbgPrint("Mp Return Packet\n");
Resvd = (PRSVD)(Packet->MiniportReserved);
MyPacket = Resvd->OriginalPkt;
NdisFreePacket(Packet);
NdisReturnPackets(&MyPacket, 1);
}
NDIS_STATUS
MPTransferData(
OUT PNDIS_PACKET Packet,
OUT PUINT BytesTransferred,
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE MiniportReceiveContext,
IN UINT ByteOffset,
IN UINT BytesToTransfer
)
/*++
Routine Description:
Miniport's transfer data handler.
Arguments:
Packet Destination packet
BytesTransferred Place-holder for how much data was copied
MiniportAdapterContext Pointer to the adapter structure
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -