summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/lt200/ltreq.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/ntos/ndis/lt200/ltreq.c651
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;
+}
+