diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/ndis/lt200/ltreq.c | 651 |
1 files changed, 651 insertions, 0 deletions
diff --git a/private/ntos/ndis/lt200/ltreq.c b/private/ntos/ndis/lt200/ltreq.c new file mode 100644 index 000000000..6b54c9915 --- /dev/null +++ b/private/ntos/ndis/lt200/ltreq.c @@ -0,0 +1,651 @@ +/*++ + +Copyright (c) 1992 Microsoft Corporation + +Module Name: + + ltreq.c + +Abstract: + + This module contains + +Author: + + Nikhil Kamkolkar (nikhilk@microsoft.com) + Stephen Hou (stephh@microsoft.com) + +Revision History: + 19 Jun 1992 Initial Version (dch@pacvax.pacersoft.com) + +Notes: Tab stop: 4 +--*/ + +#define LTREQ_H_LOCALS +#include "ltmain.h" +#include "ltreq.h" + +// Define file id for errorlogging +#define FILENUM LTREQ + + +NDIS_STATUS +LtRequest( + IN NDIS_HANDLE MacBindingHandle, + IN PNDIS_REQUEST NdisRequest + ) +/*++ + +Routine Description: + + called by NDIS to query or set card/driver information on a binding + +Arguments: + + MacBindingHandle : the binding submitting the request + NdisRequest : the request we've been asked to satisfy + +Return Values: + + NDIS_STATUS_SUCCESS : if completed successfully + NDIS_STATUS_RESET_IN_PROGRESS : if the adapter's in the middle of a reset + NDIS_STATUS_ADAPTER_REMOVED : if the adapter's been closed + NDIS_STATUS_CLOSING : if the binding is closing down + NDIS_STATUS_NOT_SUPPORTED : if we do not support the requested action + +--*/ +{ + NDIS_STATUS Status; + PLT_ADAPTER Adapter = ((PLT_OPEN)MacBindingHandle)->LtAdapter; + PLT_OPEN Open = (PLT_OPEN)MacBindingHandle; + + if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS) + { + return(NDIS_STATUS_RESET_IN_PROGRESS); + } + + switch (NdisRequest->RequestType) + { + case NdisRequestSetInformation: + case NdisRequestQueryInformation: + + // increment count since we'll be in the binding with the request + LtReferenceBinding(Open,&Status); + if (Status == NDIS_STATUS_SUCCESS) + { + if (NdisRequest->RequestType == NdisRequestSetInformation) + { + Status = LtReqSetInformation( + Adapter, + Open, + NdisRequest->DATA.SET_INFORMATION.Oid, + NdisRequest->DATA.SET_INFORMATION.InformationBuffer, + NdisRequest->DATA.SET_INFORMATION.InformationBufferLength, + &(NdisRequest->DATA.SET_INFORMATION.BytesRead), + &(NdisRequest->DATA.SET_INFORMATION.BytesNeeded)); + } + else + { + Status = LtReqQueryInformation( + Adapter, + Open, + NdisRequest->DATA.QUERY_INFORMATION.Oid, + NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer, + NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength, + &(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten), + &(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded), + FALSE); + } + + // completed the request for the binding; outa there + LtDeReferenceBinding(Open); + } + + break; + + default: + // Unkown request + + Status = NDIS_STATUS_NOT_SUPPORTED; + break; + + } + + return(Status); +} + + +NDIS_STATUS +LtReqQueryGlobalStatistics( + IN NDIS_HANDLE MacAdapterContext, + IN PNDIS_REQUEST NdisRequest + ) +/*++ + +Routine Description: + + called by NDIS to query or set global card/driver information + +Arguments: + + MacAdapterContext : the adapter the request is submitted on + NdisRequest : the request we've been asked to satisfy + +Return Values: + + NDIS_STATUS_SUCCESS : if completed successfully + NDIS_STATUS_RESET_IN_PROGRESS : if the adapter's in the middle of a reset + NDIS_STATUS_ADAPTER_REMOVED : if the adapter's been closed + NDIS_STATUS_CLOSING : if the binding is closing down + NDIS_STATUS_NOT_SUPPORTED : if we do not support the requested action + +--*/ +{ + NDIS_STATUS Status; + PLT_ADAPTER Adapter = MacAdapterContext; + + if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS) + { + return(NDIS_STATUS_RESET_IN_PROGRESS); + } + + switch (NdisRequest->RequestType) + { + case NdisRequestQueryStatistics: + + LtReferenceAdapter(Adapter,&Status); + if (Status != NDIS_STATUS_SUCCESS) + break; + + Status = LtReqQueryInformation( + Adapter, + NULL, + NdisRequest->DATA.QUERY_INFORMATION.Oid, + NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer, + NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength, + &(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten), + &(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded), + TRUE); + + LtDeReferenceAdapter(Adapter); + break; + + default: + + Status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + return(Status); +} + + +STATIC +NDIS_STATUS +LtReqSetInformation( + IN PLT_ADAPTER Adapter, + IN PLT_OPEN Open, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN INT InformationBufferLength, + IN PUINT BytesRead, + IN PUINT BytesNeeded + ) +/*++ + +Routine Description: + + performs a set operation for a single OID. + +Arguments: + + Adapter : The adapter that the set is for + Open : The binding that the set is for + Oid : The OID to set + InformationBuffer : Holds the data to be set + InformationBufferLength : The length of InformationBuffer + BytesRead : If the call is successful, returns the number + of bytes read from InformationBuffer + BytesNeeded : If there is not enough data in InformationBuffer + to satisfy the request, returns the amount of + storage needed. + +Return Value: + + NDIS_STATUS_SUCCESS : if successful + NDIS_STATUS_INVALID_OID : if the oid is not supported + NDIS_STATUS_INVALID_DATA : if InformationBuffer contains bad data + NDIS_STATUS_INVALID_LENGTH : if the InformationBufferLength is incorrect + +--*/ +{ + + ULONG PacketFilter, NewLookAhead; + NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; + + // + // Now check for the most common OIDs + // + + DBGPRINT(DBG_COMP_REQ,DBG_LEVEL_INFO, + ("LtReqSetInformation: setting OID - 0x%.8lx\n", Oid)); + + switch (Oid) + { + case OID_GEN_CURRENT_PACKET_FILTER: + + // Localtalk only supports Directed and broadcast packets. + // And the Lt firmware does not support PROMISCUSOUS mode. + // so return NDIS_STATUS_NOT_SUPPORTED for these packet filters. + + if (InformationBufferLength != 4) + { + StatusToReturn = NDIS_STATUS_INVALID_LENGTH; + break; + + } + + NdisMoveMemory( + (PVOID)&PacketFilter, + InformationBuffer, + sizeof(ULONG)); + + DBGPRINT(DBG_COMP_REQ,DBG_LEVEL_INFO, + ("LtReqSetInformation: Requested packet filter is %x\n", PacketFilter)); + + if (PacketFilter == NDIS_PACKET_TYPE_BROADCAST || + PacketFilter == NDIS_PACKET_TYPE_DIRECTED || + PacketFilter == (NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED)) + { + NdisAcquireSpinLock(&Adapter->Lock); + Adapter->GlobalPacketFilter |= PacketFilter; + Open->CurrentPacketFilter = PacketFilter; + NdisReleaseSpinLock(&Adapter->Lock); + *BytesRead = InformationBufferLength; + + } + else + { + StatusToReturn = NDIS_STATUS_INVALID_DATA; + } + + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + + if (InformationBufferLength != 4) + { + StatusToReturn = NDIS_STATUS_INVALID_LENGTH; + break; + + } + + NdisMoveMemory( + (PVOID)&NewLookAhead, + InformationBuffer, + sizeof(ULONG)); + + DBGPRINT(DBG_COMP_REQ,DBG_LEVEL_INFO, + ("LtReqSetInformation: Requested Lookahead size is %d\n", NewLookAhead)); + + if ((NewLookAhead > LT_MAX_INDICATE_SIZE) || + (NewLookAhead < LT_MIN_INDICATE_SIZE)) + { + StatusToReturn = NDIS_STATUS_INVALID_DATA; + break; + + } + + NdisAcquireSpinLock(&Adapter->Lock); + // valid lookahead size, so set it + Open->CurrentLookAheadSize = NewLookAhead; + + // adjust the global lookaheadsize + if (Adapter->GlobalLookAheadSize < NewLookAhead) + { + Adapter->GlobalLookAheadSize = NewLookAhead; + } + else + { + LtReqAdjustLookAhead( + &Adapter->GlobalLookAheadSize, + &Adapter->OpenBindings); + } + NdisReleaseSpinLock(&Adapter->Lock); + *BytesRead = 4; + break; + + default: + + StatusToReturn = NDIS_STATUS_INVALID_OID; + break; + } + + return(StatusToReturn); +} + + +LtReqQueryInformation( + IN PLT_ADAPTER Adapter, + IN PLT_OPEN Open, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN INT InformationBufferLength, + IN PUINT BytesWritten, + IN PUINT BytesNeeded, + IN BOOLEAN Global + ) +/*++ + +Routine Description: + + performs a query operation for a single OID. + +Arguments: + + Adapter : The adapter that the query is for + Open : The binding that the query is for + Oid : The OID to query + InformationBuffer : Holds the result of the query. + InformationBufferLength : The length of InformationBuffer. + BytesWritten : If the call is successful, returns the + number of bytes written to InformationBuffer + BytesNeeded : If there is not enough room in InformationBuffer + to satisfy the request, returns the amount of + storage needed + Global : TRUE if the request originated from the adapter. + FALSE if the request came from a binding + +Return Value: + + NDIS_STATUS_SUCCESS : if successful + NDIS_STATUS_INVALID_OID : if the query is on an OID we do not support + NDIS_STATUS_BUFFER_TOO_SHORT: if InformationBufferLength is too small to + hold the information returned + +--*/ +{ + + UINT OidIndex; + ULONG GenericUlong; + USHORT GenericUshort; + PVOID SourceBuffer = &GenericUlong; + UINT SourceBufferLength = sizeof(ULONG); + PNDIS_OID SupportedOidArray = LtProtocolSupportedOids; + UINT SupportedOids = (sizeof(LtProtocolSupportedOids)/sizeof(ULONG)); + static UCHAR VendorDescription[] = LT_VENDOR_DESCR; + static UCHAR VendorId[3] = LT_VENDOR_ID; + + if (Global) + { + SupportedOidArray = LtGlobalSupportedOids; + SupportedOids = sizeof(LtGlobalSupportedOids)/sizeof(ULONG); + } + + // + // Check that the OID is valid. + // + for (OidIndex=0; OidIndex < SupportedOids; OidIndex++) + { + if (Oid == SupportedOidArray[OidIndex]) + { + break; + } + } + + if (OidIndex == SupportedOids) + { + *BytesWritten = 0; + return(NDIS_STATUS_INVALID_OID); + } + + switch (Oid) + { + case OID_GEN_SUPPORTED_LIST: + + SourceBuffer = SupportedOidArray; + SourceBufferLength = SupportedOids * sizeof(ULONG); + break; + + case OID_GEN_HARDWARE_STATUS: + + GenericUlong = NdisHardwareStatusReady; + if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS) + { + GenericUlong = NdisHardwareStatusReset; + } + break; + + case OID_GEN_MEDIA_SUPPORTED: + + GenericUlong = NdisMediumLocalTalk; + break; + + case OID_GEN_MEDIA_IN_USE: + + GenericUlong = NdisMediumLocalTalk; + // if no binding exists then media is not in use + if (Global && Adapter->OpenCount == 0) + { + SourceBufferLength = 0; + } + break; + + case OID_GEN_MAXIMUM_LOOKAHEAD: + + GenericUlong = LT_MAX_INDICATE_SIZE; + break; + + case OID_GEN_MAXIMUM_FRAME_SIZE: + + GenericUlong = LT_MAXIMUM_PACKET_SIZE; + break; + + case OID_GEN_LINK_SPEED: + + GenericUlong = LT_LINK_SPEED; + break; + + case OID_GEN_TRANSMIT_BUFFER_SPACE: + + GenericUlong = LT_MAXIMUM_PACKET_SIZE; + break; + + case OID_GEN_RECEIVE_BUFFER_SPACE: + + // BUGBUG: need to determine number of recv buffers or in this case the + // amount of space for receives + GenericUlong = LT_MAXIMUM_PACKET_SIZE * 5; + break; + + case OID_GEN_TRANSMIT_BLOCK_SIZE: + + GenericUlong = 1; + break; + + case OID_GEN_RECEIVE_BLOCK_SIZE: + + // BUGBUG: need to determine number of recv buffers + GenericUlong = 5; + break; + + case OID_GEN_VENDOR_ID: + + SourceBuffer = VendorId; + SourceBufferLength = sizeof(VendorId); + break; + + case OID_GEN_VENDOR_DESCRIPTION: + + SourceBuffer = VendorDescription; + SourceBufferLength = sizeof(VendorDescription); + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + + GenericUlong = Open->CurrentPacketFilter; + if (Global) + { + GenericUlong = Adapter->GlobalPacketFilter; + } + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + + GenericUlong = Open->CurrentLookAheadSize; + if (Global) + { + GenericUlong = Adapter->GlobalLookAheadSize; + } + break; + + case OID_GEN_DRIVER_VERSION: + + GenericUshort = (LT_MAJOR_VERSION << 8) + LT_MINOR_VERSION; + SourceBuffer = &GenericUshort; + SourceBufferLength = sizeof(USHORT); + break; + + case OID_GEN_MAXIMUM_TOTAL_SIZE: + + GenericUlong = LT_MAXIMUM_PACKET_SIZE; + break; + + case OID_GEN_XMIT_OK: + case OID_GEN_RCV_OK: + case OID_GEN_XMIT_ERROR: + case OID_GEN_RCV_ERROR: + case OID_GEN_RCV_NO_BUFFER: + + OidIndex = (Oid & LT_OID_INDEX_MASK) - 1; + ASSERT(OidIndex < GM_ARRAY_SIZE); + GenericUlong = Adapter->GeneralMandatory[OidIndex]; + break; + + case OID_GEN_DIRECTED_BYTES_XMIT: + case OID_GEN_BROADCAST_BYTES_XMIT: + case OID_GEN_DIRECTED_BYTES_RCV: + case OID_GEN_BROADCAST_BYTES_RCV: + + OidIndex = (Oid & LT_OID_INDEX_MASK) - 1; + ASSERT(OidIndex < GM_ARRAY_SIZE); + SourceBuffer = &Adapter->GeneralOptionalByteCount[OidIndex / 2]; + SourceBufferLength = sizeof(LARGE_INTEGER); + break; + + case OID_GEN_DIRECTED_FRAMES_XMIT: + case OID_GEN_BROADCAST_FRAMES_XMIT: + case OID_GEN_DIRECTED_FRAMES_RCV: + case OID_GEN_BROADCAST_FRAMES_RCV: + + OidIndex = (Oid & LT_OID_INDEX_MASK) - 1; + ASSERT(OidIndex < GO_COUNT_ARRAY_SIZE); + GenericUlong = Adapter->GeneralOptionalFrameCount[OidIndex / 2]; + break; + + case OID_GEN_RCV_CRC_ERROR: + case OID_GEN_TRANSMIT_QUEUE_LENGTH: + + OidIndex = (Oid & LT_OID_INDEX_MASK) - 1; + ASSERT(OidIndex < GO_ARRAY_SIZE); + GenericUlong = Adapter->GeneralOptional[OidIndex - GO_ARRAY_START]; + break; + + case OID_GEN_MAC_OPTIONS: + + GenericUlong = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA; + break; + + case OID_LTALK_CURRENT_NODE_ID: + + SourceBuffer = &GenericUshort; + GenericUshort = Adapter->NodeId; + SourceBufferLength = 2; + break; + + case OID_LTALK_IN_BROADCASTS: + case OID_LTALK_IN_LENGTH_ERRORS: + + OidIndex = (Oid & LT_OID_INDEX_MASK) - 1; + ASSERT (OidIndex < MM_ARRAY_SIZE); + GenericUlong = Adapter->MediaMandatory[OidIndex]; + break; + + case OID_LTALK_OUT_NO_HANDLERS: + case OID_LTALK_DEFERS: + + OidIndex = (Oid & LT_OID_INDEX_MASK) - 1; + ASSERT (OidIndex < MO_ARRAY_SIZE); + GenericUlong = Adapter->MediaOptional[OidIndex]; + break; + + default: + + // should never get here + ASSERT(FALSE); + break; + } + + if ((INT)SourceBufferLength > InformationBufferLength) + { + *BytesNeeded = SourceBufferLength; + return(NDIS_STATUS_BUFFER_TOO_SHORT); + } + + NdisMoveMemory( + InformationBuffer, + SourceBuffer, + SourceBufferLength); + + *BytesWritten = SourceBufferLength; + + return(NDIS_STATUS_SUCCESS); +} + + +STATIC +VOID +LtReqAdjustLookAhead( + OUT PUINT GlobalLookAheadSize, + IN PLIST_ENTRY OpenBindings + ) +/*++ + +Routine Description: + + called by LtReqSetInformation to adjust the global lookahead size when + the previously largest lookahead size (on a binding) is adjusted + + THIS ROUTINE IS CALLED WITH THE SPINLOCK HELD + +Arguments: + + GlobalLookAheadSize : the global lookahead param we're adjusting + OpenBindings : the list of bindings we need to traverse + +Return Value: + + none + +--*/ +{ + PLT_OPEN Binding; + PLIST_ENTRY p = OpenBindings->Flink; + UINT MaxLookAheadSize = 0; + + while(p != OpenBindings) + { + Binding = CONTAINING_RECORD( + p, + LT_OPEN, + Linkage); + + if (Binding->CurrentLookAheadSize > MaxLookAheadSize) + { + MaxLookAheadSize = Binding->CurrentLookAheadSize; + } + p = p->Flink; + } + *GlobalLookAheadSize = MaxLookAheadSize; +} + |