summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/ne3200/command.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/ndis/ne3200/command.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/ndis/ne3200/command.c')
-rw-r--r--private/ntos/ndis/ne3200/command.c272
1 files changed, 272 insertions, 0 deletions
diff --git a/private/ntos/ndis/ne3200/command.c b/private/ntos/ndis/ne3200/command.c
new file mode 100644
index 000000000..1e3bee680
--- /dev/null
+++ b/private/ntos/ndis/ne3200/command.c
@@ -0,0 +1,272 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ command.c
+
+Abstract:
+
+ This file contains the code for managing Command Blocks on the
+ NE3200's Command Queue.
+
+Author:
+
+ Keith Moore (KeithMo) 07-Feb-1991
+
+Environment:
+
+Revision History:
+
+
+--*/
+
+#include <ne3200sw.h>
+
+
+VOID
+FASTCALL
+Ne3200Stall(
+ PULONG Dummy
+ )
+/*++
+
+Routine Description:
+
+ This routine is used to cause the processor to spin momentarily,
+ without actually having to stall for a full microsecond, as in
+ NdisStallExecution.
+
+Arguments:
+
+ Dummy - A variable to increment.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ (*Dummy)++;
+}
+
+
+VOID
+NE3200AcquirePublicCommandBlock(
+ IN PNE3200_ADAPTER Adapter,
+ OUT PNE3200_SUPER_COMMAND_BLOCK * CommandBlock
+ )
+
+/*++
+
+Routine Description:
+
+ Gets a public command block.
+
+Arguments:
+
+ Adapter - The adapter that points to the ring entry structures.
+
+ CommandBlock - Will receive a pointer to a Command Block.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // This is a pointer to the "public" Command Block.
+ //
+ PNE3200_SUPER_COMMAND_BLOCK PublicCommandBlock =
+ Adapter->PublicCommandQueue + Adapter->NextPublicCommandBlock;
+
+
+ ASSERT(Adapter->NumberOfPublicCommandBlocks > 0);
+
+ //
+ // Remove a command block count.
+ //
+ Adapter->NumberOfPublicCommandBlocks--;
+
+ //
+ // Initialize the Command Block.
+ //
+ NdisZeroMemory(
+ PublicCommandBlock,
+ sizeof(NE3200_SUPER_COMMAND_BLOCK)
+ );
+
+ PublicCommandBlock->Hardware.NextPending = NE3200_NULL;
+ PublicCommandBlock->AvailableCommandBlockCounter =
+ &Adapter->NumberOfPublicCommandBlocks;
+ NdisSetPhysicalAddressLow(
+ PublicCommandBlock->Self,
+ NdisGetPhysicalAddressLow(Adapter->PublicCommandQueuePhysical) +
+ Adapter->NextPublicCommandBlock * sizeof(NE3200_SUPER_COMMAND_BLOCK));
+
+ //
+ // Increment to next command block
+ //
+ Adapter->NextPublicCommandBlock++;
+ if (Adapter->NextPublicCommandBlock == NE3200_NUMBER_OF_PUBLIC_CMD_BLOCKS) {
+ Adapter->NextPublicCommandBlock = 0;
+ }
+
+ IF_LOG('q');
+
+ //
+ // Return the Command Block pointer.
+ //
+ *CommandBlock = PublicCommandBlock;
+
+ IF_NE3200DBG(ACQUIRE) {
+
+ DPrint2(
+ "Acquired public command block @ %08lX\n",
+ (ULONG)PublicCommandBlock
+ );
+
+ }
+
+}
+
+
+VOID
+FASTCALL
+NE3200RelinquishCommandBlock(
+ IN PNE3200_ADAPTER Adapter,
+ IN PNE3200_SUPER_COMMAND_BLOCK CommandBlock
+ )
+
+/*++
+
+Routine Description:
+
+ Relinquish the Command Block resource. If this is a "public"
+ Command Block, then update the CommandQueue. If this is a
+ "private" Command Block, then free to the private command queue.
+
+Arguments:
+
+ Adapter - The adapter that owns the Command Block.
+
+ CommandBlock - The Command Block to relinquish.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ IF_NE3200DBG(SUBMIT) {
+
+ DPrint2(
+ "Relinquishing command @ %08lX\n",
+ (ULONG)NdisGetPhysicalAddressLow(CommandBlock->Self)
+ );
+
+ }
+
+ //
+ // If this is the last pending command block, then we
+ // can remove the adapter's last pending command pointer.
+ //
+ if (CommandBlock == Adapter->LastCommandOnCard) {
+
+ //
+ // If there is another waiting chain of commands -- submit those
+ //
+ if (Adapter->FirstWaitingCommand != NULL) {
+
+ //
+ // Move the chain to the on card queue.
+ //
+ Adapter->FirstCommandOnCard = Adapter->FirstWaitingCommand;
+ Adapter->LastCommandOnCard = Adapter->LastWaitingCommand;
+ Adapter->FirstWaitingCommand = NULL;
+
+ IF_NE3200DBG(SUBMIT) {
+
+ DPrint2(
+ "Starting command @ %08lX\n",
+ (ULONG)NdisGetPhysicalAddressLow(Adapter->FirstCommandOnCard->Self)
+ );
+
+ }
+
+ //
+ // Submit this command chain to the card.
+ //
+ NE3200_WRITE_COMMAND_POINTER(
+ Adapter,
+ NdisGetPhysicalAddressLow(Adapter->FirstCommandOnCard->Self)
+ );
+
+ //
+ // Stall momentarily for the adapter to get the command.
+ //
+ {
+ ULONG i;
+ Ne3200Stall(&i);
+ }
+
+ //
+ // Inform the card of the command
+ //
+ NE3200_WRITE_LOCAL_DOORBELL_INTERRUPT(
+ Adapter,
+ NE3200_LOCAL_DOORBELL_NEW_COMMAND
+ );
+
+ } else {
+
+ //
+ // No commands are pending, clear the on card queue
+ //
+ Adapter->FirstCommandOnCard = NULL;
+
+ }
+
+ } else {
+
+ //
+ // Point the adapter's first pending command to the
+ // next command on the command queue.
+ //
+ Adapter->FirstCommandOnCard = CommandBlock->NextCommand;
+
+ }
+
+ //
+ // Free this command block
+ //
+ CommandBlock->Hardware.NextPending = NE3200_NULL;
+ CommandBlock->Hardware.State = NE3200_STATE_FREE;
+
+ //
+ // Update the correct queue.
+ //
+ (*CommandBlock->AvailableCommandBlockCounter)++;
+
+#if DBG
+ if (CommandBlock->AvailableCommandBlockCounter == &Adapter->NumberOfAvailableCommandBlocks) {
+ //
+ // This is a "private" Command Block.
+ //
+ IF_LOG('A');
+ } else {
+ //
+ // This is a "public" Command Block.
+ //
+ IF_LOG('Q');
+ }
+#endif
+
+}
+