📄 interrup.c
字号:
/*++
Copyright (c) 1998-2001 ASIX Electronics Corporation
Module Name:
interrup.c
Abstract:
This is a part of the driver for the ASIX AX88172 USB-Ethernet controller.
This driver conforms to the NDIS 3.0 interface.
Author:
William Lee, November. 1999, July 2002,
Environment:
Kernel Mode.
Revision History:
08-Dec-1999, Add USBD Call for CDC spec.
26-Apr-2000, Change Bulk In/Out to be continuous without SOF waiting.
12-Aug-2000, Use Vendor Functions instead of Class Functions.
--*/
#define min(a,b) (((a) < (b)) ? (a) : (b))
VOID
AX88172DoNextSend(
PAX_ADAPTER Adapter
)
//*++
//
//Routine Description:
// This routine examines if the packet at the head of the packet
// list can be copied to the adapter, and does so.
//
//Arguments:
// Adapter - Pointer to the adapter block.
//
//Return Value:
// None
//
//--*
{
//
// The packet to process.
PNDIS_PACKET Packet;
//
// Current NDIS_BUFFER that is being copied from
PNDIS_BUFFER CurBuffer;
PVOID DummyPVOID;
UINT DummyUINT;
//
// Length of each of the buffers
UINT CopyBytes;
//
// Addresses of the Buffers to copy from and to.
PUCHAR DestinationAddress;
//
// Remove the packet from the queue.
NdisAcquireSpinLock( &Adapter->TransmitSpinLock );
Packet = Adapter->FirstPacket;
Adapter->FirstPacket = RESERVED(Packet)->Next;
NdisReleaseSpinLock( &Adapter->TransmitSpinLock );
Adapter->NumQueuePackets--;
DestinationAddress = Adapter->TransmitBuffer[Adapter->FirstTransmit];
CopyBytes = RESERVED(Packet)->TotalPacketLength;
if ( CopyBytes % Adapter->MaximumPacketSize )
Adapter->TransmitLength[Adapter->FirstTransmit] = CopyBytes;
else
Adapter->TransmitLength[Adapter->FirstTransmit] = CopyBytes+1;
NdisGetFirstBufferFromPacket(
Packet,
&CurBuffer,
&DummyPVOID,
&DummyUINT,
&DummyUINT
);
while (CurBuffer)
{
UINT CopyLength;
PUCHAR SourceAddress;
NdisQueryBuffer(
CurBuffer,
(PVOID *)&SourceAddress,
&CopyLength
);
if (CopyBytes <= CopyLength)
{
NdisMoveMemory(
DestinationAddress,
SourceAddress,
CopyBytes
);
break;
}
NdisMoveMemory(
DestinationAddress,
SourceAddress,
CopyLength
);
CopyBytes -= CopyLength;
DestinationAddress += CopyLength;
NdisGetNextBuffer(
CurBuffer,
&CurBuffer
);
}
if ( Adapter->FirstTransmit<(numTransmitQ-1) )
Adapter->FirstTransmit++;
else
Adapter->FirstTransmit = 0;
{
ULONG IoCount;
NdisAcquireSpinLock( &Adapter->TransmitIoCountSpinLock );
IoCount = NdisInterlockedIncrement(&Adapter->TransmitIoCount);
NdisReleaseSpinLock( &Adapter->TransmitIoCountSpinLock );
if ( IoCount==1 )
BulkUsb_PacketTransmit( Adapter );
}
NdisMSendComplete(
Adapter->MiniportAdapterHandle,
Packet,
NDIS_STATUS_SUCCESS
);
}
NDIS_STATUS
AX88172TransferData(
OUT PNDIS_PACKET Packet,
OUT PUINT BytesTransferred,
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE MiniportReceiveContext,
IN UINT ByteOffset,
IN UINT BytesToTransfer
)
//*++
//
//Routine Description:
// A protocol calls the AX88172TransferData request (indirectly via
// NdisTransferData) from within its Receive event handler
// to instruct the driver to copy the contents of the received packet
// a specified packet buffer.
//
//Arguments:
// MiniportAdapterContext - Context registered with the wrapper, really
// a pointer to the adapter.
// MiniportReceiveContext - The context value passed by the driver on its call
// to NdisMEthIndicateReceive. The driver can use this value to determine
// which packet, on which adapter, is being received.
// ByteOffset - An unsigned integer specifying the offset within the
// received packet at which the copy is to begin. If the entire packet
// is to be copied, ByteOffset must be zero.
// BytesToTransfer - An unsigned integer specifying the number of bytes
// to copy. It is legal to transfer zero bytes; this has no effect. If
// the sum of ByteOffset and BytesToTransfer is greater than the size
// of the received packet, then the remainder of the packet (starting from
// ByteOffset) is transferred, and the trailing portion of the receive
// buffer is not modified.
// Packet - A pointer to a descriptor for the packet storage into which
// the MAC is to copy the received packet.
// BytesTransfered - A pointer to an unsigned integer. The MAC writes
// the actual number of bytes transferred into this location. This value
// is not valid if the return status is STATUS_PENDING.
//
//Notes:
// - The MacReceiveContext will be a pointer to the open block for
// the packet.
//
//--*
{
//
// The adapter to transfer from.
PAX_ADAPTER Adapter = ((PAX_ADAPTER)MiniportReceiveContext);
//
// Current NDIS_BUFFER to copy into
PNDIS_BUFFER CurrentBuffer;
//
// Variables for the number of bytes to copy, how much can be
// copied at this moment, and the total number of bytes to copy.
UINT BytesLeft;
//
// Add the packet header onto the offset.
ByteOffset += ETH_HEADER_SIZE;
//
// Set the number of bytes left to transfer
BytesLeft = BytesToTransfer;
//
// Get location to copy into
NdisQueryPacket(
Packet,
NULL,
NULL,
&CurrentBuffer,
NULL
);
//
// Loop, filling each buffer in the packet until there
// are no more buffers or the data has all been copied.
while (CurrentBuffer && BytesLeft)
{
//
// Virtual address of the buffer.
PUCHAR BufferOffset;
//
// Length and offset into the buffer.
UINT BufferLength, uMoveSize;
NdisQueryBuffer(
CurrentBuffer,
(PVOID *)&BufferOffset,
&BufferLength
);
NdisGetNextBuffer(
CurrentBuffer,
&CurrentBuffer
);
if (BufferLength == 0)
continue;
//
// See how much data to read into this buffer.
uMoveSize = min(BytesLeft, BufferLength);
NdisMoveMemory(
BufferOffset,
&Adapter->ReceiveBuffer[Adapter->LastReceive][ByteOffset],
uMoveSize
);
ByteOffset += uMoveSize;
BytesLeft -= uMoveSize;
}
*BytesTransferred = BytesToTransfer - BytesLeft;
return NDIS_STATUS_SUCCESS;
}
NDIS_STATUS
AX88172Send(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT Flags
)
/*++
Routine Description:
The AX88172Send request instructs a driver to transmit a packet through
the adapter onto the medium.
Arguments:
MiniportAdapterContext - Context registered with the wrapper,
really a pointer to the adapter.
Packet - A pointer to a descriptor for the packet
that is to be transmitted.
SendFlags - Optional send flags
Notes:
This miniport driver will always accept a send. This is because
the AX88172 has limited send resources and the driver needs packets
to copy to the adapter immediately after a transmit completes in
order to keep the adapter as busy as possible.
This is not required for other adapters, as they have enough
resources to keep the transmitter busy until the wrapper submits
the next packet.
--*/
{
PAX_ADAPTER Adapter = (PAX_ADAPTER)(MiniportAdapterContext);
//
// Current NDIS_BUFFER that is being copied from
PNDIS_BUFFER CurBuffer;
//
// Length of the packet
ULONG Len;
// If the adapter is under reset, we should reject TX operation.
if ( !Adapter->fgReady ||Adapter->HaltEvents )
return NDIS_STATUS_SUCCESS;
//
// Get the length of the packet.
NdisQueryPacket(
Packet,
NULL,
NULL,
&CurBuffer,
&Len
);
if ( (Len <ETH_HEADER_SIZE) || (Len >1514) )
return NDIS_STATUS_INVALID_PACKET;
RESERVED(Packet)->TotalPacketLength = Len;
RESERVED(Packet)->Next = NULL;
//
// Put the packet on the send queue.
Adapter->NumQueuePackets++;
NdisAcquireSpinLock( &Adapter->TransmitSpinLock );
if (Adapter->FirstPacket == NULL)
Adapter->FirstPacket = Packet;
else
RESERVED(Adapter->LastPacket)->Next = Packet;
Adapter->LastPacket = Packet;
NdisReleaseSpinLock( &Adapter->TransmitSpinLock );
if ( !Adapter->StartTransmit )
{
Adapter->StartTransmit = TRUE;
NdisMSetTimer( &Adapter->TransmitHandleTimer,0 );
}
return NDIS_STATUS_PENDING;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -