Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

371 lines
9.9 KiB

/*++
Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved.
Module Name:
request.c
Abstract:
This module contains the request calls to the miniport driver below.
Author:
Anil Francis Thomas (10/98)
Environment:
Kernel
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#define MODULE_ID MODULE_REQUEST
NDIS_STATUS
AtmSmCoRequest(
IN NDIS_HANDLE ProtocolAfContext,
IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
IN OUT PNDIS_REQUEST pNdisRequest
)
/*++
Routine Description:
This routine is called by NDIS when our Call Manager sends us an
NDIS Request. NDIS Requests that are of significance to us are:
- OID_CO_ADDRESS_CHANGE
The set of addresses registered with the switch has changed,
i.e. address registration is complete. We issue an NDIS Request
ourselves to get the list of addresses registered.
- OID_CO_AF_CLOSE
The Call Manager wants us to shut down this Interface.
We ignore all other OIDs.
Arguments:
ProtocolAfContext - Our context for the Address Family binding,
which is a pointer to the ATMSM Interface.
ProtocolVcContext - Our context for a VC, which is a pointer to
an ATMSM VC structure.
ProtocolPartyContext - Our context for a Party. Since we don't do
PMP, this is ignored (must be NULL).
pNdisRequest - Pointer to the NDIS Request.
Return Value:
NDIS_STATUS_SUCCESS if we recognized the OID
--*/
{
PATMSM_ADAPTER pAdapt= (PATMSM_ADAPTER)ProtocolAfContext;
BOOLEAN ValidAf;
DbgInfo(("CallMgrRequest: Request %lx, Type %d, OID %x\n",
pNdisRequest, pNdisRequest->RequestType,
pNdisRequest->DATA.SET_INFORMATION.Oid));
switch(pNdisRequest->DATA.SET_INFORMATION.Oid){
case OID_CO_ADDRESS_CHANGE:
DbgInfo(("Received: OID_CO_ADDRESS_CHANGE\n"));
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
pAdapt->ulFlags |= ADAPT_ADDRESS_INVALID;
ValidAf = ((pAdapt->ulFlags & ADAPT_AF_OPENED) != 0);
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
if (ValidAf)
AtmSmQueryAdapterATMAddresses(pAdapt);
break;
case OID_CO_AF_CLOSE:
DbgInfo(("Received: OID_CO_AF_CLOSE\n"));
if (AtmSmReferenceAdapter(pAdapt)){
AtmSmShutdownAdapter(pAdapt);
AtmSmDereferenceAdapter(pAdapt);
}
break;
default:
break;
}
return NDIS_STATUS_SUCCESS;
}
VOID
AtmSmCoRequestComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolAfContext,
IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
IN PNDIS_REQUEST pNdisRequest
)
/*++
Routine Description:
This routine is called by NDIS when a previous call to NdisCoRequest
that had pended, is complete. We handle this based on the request
we had sent, which has to be one of:
- OID_CO_GET_ADDRESSES
Get all addresses registered on the specified AF binding.
Arguments:
Status - Status of the Request.
ProtocolAfContext - Our context for the Address Family binding,
which is a pointer to the PATMSM_ADAPTER.
ProtocolVcContext - Our context for a VC, which is a pointer to
a VC structure.
ProtocolPartyContext - Our context for a Party
pNdisRequest - Pointer to the NDIS Request.
Return Value:
None
--*/
{
PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)ProtocolAfContext;
DbgInfo(("CoRequestComplete: Request %lx, Type %d, OID %lx\n",
pNdisRequest, pNdisRequest->RequestType,
pNdisRequest->DATA.QUERY_INFORMATION.Oid));
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
switch(pNdisRequest->DATA.SET_INFORMATION.Oid){
case OID_CO_GET_ADDRESSES:
if (NDIS_STATUS_SUCCESS == Status){
PCO_ADDRESS_LIST pCoAddrList;
UINT i;
pCoAddrList = (PCO_ADDRESS_LIST)(pNdisRequest->DATA.
QUERY_INFORMATION.InformationBuffer);
ASSERT(pCoAddrList->NumberOfAddresses == 1);
ASSERT(pCoAddrList->NumberOfAddressesAvailable == 1);
DbgInfo(("CoRequestComplete: Configured address, %d/%d Size %d\n",
pCoAddrList->NumberOfAddresses,
pCoAddrList->NumberOfAddressesAvailable,
pCoAddrList->AddressList.AddressSize));
ASSERT(pCoAddrList->AddressList.AddressSize == (sizeof(CO_ADDRESS)
+ sizeof(ATM_ADDRESS)));
NdisMoveMemory(&pAdapt->ConfiguredAddress,
pCoAddrList->AddressList.Address,
sizeof(ATM_ADDRESS));
// set the selector byte
pAdapt->ConfiguredAddress.Address[ATM_ADDRESS_LENGTH-1] =
pAdapt->SelByte;
pAdapt->ulFlags &= ~ADAPT_ADDRESS_INVALID;
DbgInfo(("CoRequestComplete: Configured Address : "));
DumpATMAddress(ATMSMD_ERR, "", &pAdapt->ConfiguredAddress);
} else {
DbgErr(("CoRequestComplete: CO_GET_ADDRESS Failed %lx\n", Status));
}
break;
}
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
AtmSmFreeMem(pNdisRequest);
}
VOID
AtmSmSendAdapterNdisRequest(
IN PATMSM_ADAPTER pAdapt,
IN NDIS_OID Oid,
IN PVOID pBuffer,
IN ULONG BufferLength
)
/*++
Routine Description:
NDIS Request generator, for sending NDIS requests to the miniport.
Arguments:
pAdapt Ptr to Adapter
Oid The parameter being queried
pBuffer Points to parameter
BufferLength Length of above
Return Value:
None
--*/
{
NDIS_STATUS Status;
PNDIS_REQUEST pRequest;
AtmSmAllocMem(&pRequest, PNDIS_REQUEST, sizeof(NDIS_REQUEST));
if (NULL == pRequest) {
DbgErr(("AdapterRequest - Not enough memory\n"));
return;
}
NdisZeroMemory(pRequest, sizeof(NDIS_REQUEST));
//
// Query for the line rate.
//
pRequest->DATA.QUERY_INFORMATION.Oid = Oid;
pRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
pRequest->DATA.QUERY_INFORMATION.InformationBufferLength = BufferLength;
pRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
pRequest->DATA.QUERY_INFORMATION.BytesNeeded = BufferLength;
RESET_BLOCK_STRUCT(&pAdapt->RequestBlock);
NdisRequest(&Status,
pAdapt->NdisBindingHandle,
pRequest);
if (NDIS_STATUS_PENDING == Status) {
Status = WAIT_ON_BLOCK_STRUCT(&pAdapt->RequestBlock);
} else {
AtmSmRequestComplete(
pAdapt,
pRequest,
Status);
}
}
VOID
AtmSmRequestComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST pRequest,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Completion of our call to NdisRequest(). Do some follow-up.
Arguments:
ProtocolBindingContext Pointer to Adapter
pRequest The request that just completed
Status Status of NdisRequest()
Return Value:
None
--*/
{
PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)ProtocolBindingContext;;
switch (pRequest->DATA.QUERY_INFORMATION.Oid) {
case OID_ATM_MAX_AAL5_PACKET_SIZE:
if(NDIS_STATUS_SUCCESS != Status) {
DbgWarn(("Failed to get Miniport MaxPacketSize. "
"Status - %x\n", Status));
pAdapt->MaxPacketSize = DEFAULT_MAX_PACKET_SIZE;
}
if (pAdapt->MaxPacketSize < pAdapt->VCFlowSpec.SendMaxSize) {
pAdapt->VCFlowSpec.SendMaxSize =
pAdapt->VCFlowSpec.ReceiveMaxSize = pAdapt->MaxPacketSize;
}
DbgInfo(("Miniport Max AAL5 Packet Size: %d (decimal)\n",
pAdapt->MaxPacketSize));
break;
case OID_GEN_CO_LINK_SPEED: {
PNDIS_CO_LINK_SPEED pLinkSpeed = &pAdapt->LinkSpeed;
if(NDIS_STATUS_SUCCESS != Status) {
DbgWarn(("Failed to get Miniport LinkSpeed. "
"Status - %x\n", Status));
pAdapt->LinkSpeed.Inbound = pAdapt->LinkSpeed.Outbound =
DEFAULT_SEND_BANDWIDTH;
}
//
// Convert to bytes/sec
//
pLinkSpeed->Outbound = (pLinkSpeed->Outbound * 100 / 8);
pLinkSpeed->Inbound = (pLinkSpeed->Inbound * 100 / 8);
if (pLinkSpeed->Outbound < pAdapt->VCFlowSpec.SendBandwidth) {
pAdapt->VCFlowSpec.SendBandwidth = pLinkSpeed->Outbound;
}
if (pLinkSpeed->Inbound < pAdapt->VCFlowSpec.ReceiveBandwidth){
pAdapt->VCFlowSpec.ReceiveBandwidth = pLinkSpeed->Inbound;
}
DbgInfo(("Miniport Link Speed (decimal, bytes/sec): In %d, "
"Out %d\n", pLinkSpeed->Inbound, pLinkSpeed->Outbound));
break;
}
default:
ASSERT(FALSE);
break;
}
AtmSmFreeMem(pRequest);
SIGNAL_BLOCK_STRUCT(&pAdapt->RequestBlock , Status);
}