📄 csosfun.c
字号:
//**********************************************************************
//
// Filename: CsOSFun.c
//
// Description:
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to
// use this source code. For a copy of the EULA, please see the
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved
//
//**********************************************************************
#include "ndis4cs8950.h"
#include "cs8950hw.h"
extern WORD GetTheIndexOfAFreePakcet( PCHIP pChip);
extern WORD AddAFreePakcetToQ(PCHIP pChip, WORD index);
//****************************************************************************
// CrystalInterruptService()
//****************************************************************************
extern VOID CrystalInterruptService(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueDpc,
IN PVOID Context
)
/*++
Routine Description:
Interrupt service routine. This routine only gets
called during initial initialization of the adapter.
Arguments:
InterruptRecognized - Boolean value which returns TRUE if the
ISR recognizes the interrupt as coming from this adapter.
QueueDpc - TRUE if a DPC should be queued.
Context - Really a pointer to the adapter.
Return Value:
Returns true if the card ISR is non-zero.
--*/
{
NDIS_HANDLE MiniportAdapterContext = Context;
VPM_SetupMiniContext;
*InterruptRecognized = TRUE;
*QueueDpc = TRUE;
return;
}
//****************************************************************************
// CrystalInterruptService()
//****************************************************************************
VOID CrystalHandleInterrupt(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
This DPR routine is queued by the wrapper after every interrupt
and also by other routines within the driver that notice that
some deferred processing needs to be done. It's main
job is to call the interrupt processing code.
Arguments:
MiniportAdapterContext - Really a pointer to the adapter.
Return Value:
None.
--*/
{
WORD Result=TRUE;
VPM_SetupMiniContext;
if (pvMini_Context->CurrentState == NdisHardwareStatusInitializing) {
return;
} /* endif */
while (Result) { // Loop until ISR indicates there was nothing to do
Result = VchipISR( pvMini_Context->pChip );
} /* endwhile */
return;
}
//****************************************************************************
// CrystalTransferData()
//****************************************************************************
extern NDIS_STATUS CrystalTransferData(
OUT PNDIS_PACKET Packet,
OUT PUINT BytesTransferred,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE MacReceiveContext,
IN UINT ByteOffset,
IN UINT BytesToTransfer
)
/*++
Routine Description:
A protocol calls the CrystalTransferData request (indirectly via
NdisTransferData) from within its Receive event handler
to instruct the driver to copy the contents of the received packet
a specified paqcket buffer.
Arguments:
MiniportAdapterContext - Context registered with the wrapper, really
a pointer to the VP context.
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.
Return Value:
The function value is the status of the operation.
--*/
{
FRAG (*Frags)[MAX_FRAGS];
UINT ProtocolBufferCount;
PNDIS_BUFFER pProtocolBuffer;
UINT ProtocolTotalBufferLength;
PUCHAR pProtocolVBuffer;
ULONG ProtocolVBufferLength;
PUCHAR pSource;
UINT FragIndex=0;
UINT CurrentSize, CurrentFragSize;
UINT BytesLeftToCopy;
UINT BytesSkipped;
PRECEIVE_CONTEXT pReceiveContext;
PCHIP pChip;
pReceiveContext = (PVOID)MacReceiveContext;
if (BytesToTransfer>pReceiveContext->FrameSize) {
*BytesTransferred = 0;
return NDIS_STATUS_FAILURE;
}
pChip = pReceiveContext->pChip;
Frags = (PVOID)pReceiveContext->pFrag;
pSource = Frags[0]->pBuffer;
CurrentFragSize = Frags[0]->BuffLength;
NdisQueryPacket( Packet,
NULL,
&ProtocolBufferCount,
&pProtocolBuffer,
&ProtocolTotalBufferLength
);
NdisQueryBuffer(
pProtocolBuffer,
&pProtocolVBuffer,
&ProtocolVBufferLength
);
ByteOffset += VP_HEADERSIZE;
// Find First frag from Byte Offset
for (BytesSkipped=0;
BytesSkipped < ByteOffset;
BytesSkipped += Frags[FragIndex++]->BuffLength ) {
if ((Frags[FragIndex]->BuffLength+BytesSkipped) > ByteOffset ) {
pSource = Frags[FragIndex]->pBuffer + (ByteOffset-BytesSkipped);
CurrentFragSize = Frags[FragIndex]->BuffLength - (ByteOffset-BytesSkipped);
break;
} /* endif */
} /* endfor */
// setup curfraglength
for (*BytesTransferred = 0, FragIndex = 0,
BytesLeftToCopy = BytesToTransfer;
*BytesTransferred < BytesToTransfer ;
BytesLeftToCopy-=CurrentSize,*BytesTransferred+=CurrentSize,
ProtocolVBufferLength-=CurrentSize, CurrentFragSize-=CurrentSize) {
if (FragIndex >= pReceiveContext->FragCount) {
return NDIS_STATUS_FAILURE;
}
if (ProtocolVBufferLength == 0) {
NdisGetNextBuffer(
pProtocolBuffer,
&pProtocolBuffer
);
NdisQueryBuffer(
pProtocolBuffer,
&pProtocolVBuffer,
&ProtocolVBufferLength
);
} /* endif */
if (CurrentFragSize == 0) {
CurrentFragSize = Frags[++FragIndex]->BuffLength;
pSource = Frags[FragIndex]->pBuffer;
} /* endif */
CurrentSize = BytesLeftToCopy;
if ( Frags[FragIndex]->BuffLength < CurrentSize) {
CurrentSize = Frags[FragIndex]->BuffLength;
} /* endif */
if ( ProtocolVBufferLength < CurrentSize) {
CurrentSize = ProtocolVBufferLength;
} /* endif */
NdisMoveMemory( pProtocolVBuffer, pSource, CurrentSize );
pProtocolVBuffer += CurrentSize;
pSource += CurrentSize;
} /* endfor */
return NDIS_STATUS_SUCCESS;
}
//****************************************************************************
// SendPacketToVChip()
//****************************************************************************
NDIS_STATUS SendPacketToVChip(PCHIP pChip, PNDIS_PACKET Packet)
{
UINT PhysicalBufferCount;
UINT VirtualBufferCount;
PNDIS_BUFFER pNDISBuffer;
PVOID pVirtualBuffer;
UINT VirtualBufferLength;
UINT PacketLength;
WORD BufferHeld;
WORD FragIndex = 0;
PCD pCD;
BYTE *pTxBuff;
pCD = pChip->pData;
pTxBuff = pCD->TxBuff[pCD->TxReqIndex].pBuff;
NdisQueryPacket( Packet,
&PhysicalBufferCount,
&VirtualBufferCount,
&pNDISBuffer,
&PacketLength
);
if(pNDISBuffer == NULL) {
DEBUGMSG(ZONE_ERROR,(TEXT("SendPacketToVChip Failed \n")));
return NDIS_STATUS_FAILURE;
} /* endif */
if(PacketLength > 1514) {
VchipSend( pChip,
(DWORD)Packet,
(WORD)PacketLength);
return NDIS_STATUS_SUCCESS;
} /* endif */
NdisQueryBuffer(
pNDISBuffer,
&pVirtualBuffer,
&VirtualBufferLength
);
while (VirtualBufferCount--) {
if ((pVirtualBuffer != NULL) && (VirtualBufferLength != 0)) {
NdisMoveMemory( pTxBuff, pVirtualBuffer, VirtualBufferLength);
pTxBuff += VirtualBufferLength;
} /* endif */
if (VirtualBufferCount != 0) {
NdisGetNextBuffer(
pNDISBuffer,
&pNDISBuffer
);
if (pNDISBuffer != NULL) {
NdisQueryBuffer(
pNDISBuffer,
&pVirtualBuffer,
&VirtualBufferLength
);
} else {
pVirtualBuffer = NULL;
} /* endif */
} /* endif */
} /* endwhile */
BufferHeld = VchipSend( pChip,
(DWORD)Packet,
(WORD)PacketLength);
if (BufferHeld) {
return NDIS_STATUS_PENDING;
} else {
return NDIS_STATUS_SUCCESS;
} /* endif */
};
//****************************************************************************
// CrystalSend()
//****************************************************************************
extern NDIS_STATUS CrystalSend(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT SendFlags
)
/*++
Routine Description:
The CrystalSend 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 Virtual Protocol context.
Packet - A pointer to a descriptor for the packet that is to be
transmitted.
SendFlags - Optional send flags
Return Value:
The function value is the status of the operation.
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PTXQUEUEELEMENT pTxQueueElem;
WORD LoopCount = 0;
PNDIS_PACKET pTempTxPacket;
PTXQUEUEELEMENT pTempTxQueueElem;
VPM_SetupMiniContext;
if ((pvMini_Context->CurrentState != NdisHardwareStatusReady) ||
(pvMini_Context->CableConnected == NdisMediaStateDisconnected)) {
return NDIS_STATUS_SUCCESS;
}
if (pvMini_Context->XmitQueueDepth >= pChip->Config.MaxTxCount) {
return NDIS_STATUS_RESOURCES;
}
pTxQueueElem = (PVOID)&Packet->MiniportReserved;
pvMini_Context->XmitQueueDepth++;
if (pvMini_Context->TxQueueHead == NULL) { // Queue Empty
pvMini_Context->TxQueueHead = Packet;
} else { // Queue Not Empty
// Run the Queue to the End
for (pTempTxPacket=pvMini_Context->TxQueueHead,
pTempTxQueueElem=(PVOID)&pTempTxPacket->MiniportReserved ;
pTempTxQueueElem->NextPacket != NULL ;
pTempTxPacket = pTempTxQueueElem->NextPacket,
pTempTxQueueElem=(PVOID)&pTempTxPacket->MiniportReserved
, LoopCount++
) {
if ((DWORD)pTempTxPacket == (DWORD)Packet) {
return NDIS_STATUS_INVALID_PACKET;
}
} /* endfor */
// Put Current Element on the end of the queue
pTempTxQueueElem->NextPacket = Packet;
} /* endif */
pTxQueueElem->NextPacket = NULL;
pTxQueueElem->XmitRC = NDIS_STATUS_NOT_INDICATING;
Status = SendPacketToVChip( pChip, Packet );
if ((Status != NDIS_STATUS_PENDING) && (Status != NDIS_STATUS_SUCCESS))
{
pTxQueueElem->XmitRC = Status;
// Dequeue the last element
if (pvMini_Context->TxQueueHead == Packet) {
pvMini_Context->TxQueueHead = NULL;
} else {
pTempTxQueueElem->NextPacket = NULL;
} /* endif */
pvMini_Context->XmitQueueDepth--;
} else {
if (pTxQueueElem->XmitRC == NDIS_STATUS_NOT_INDICATING) { // Send did not complete
pTxQueueElem->XmitRC = Status = NDIS_STATUS_PENDING;
} else {
Status = pTxQueueElem->XmitRC;
} /* endif */
} /* endif */
return Status;
}
//****************************************************************************
// CrystalSendPackets()
//****************************************************************************
extern VOID CrystalSendPackets(
IN NDIS_HANDLE MiniportAdapterContext,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets
)
{
UINT i;
NDIS_STATUS Status;
for (i=0; i<NumberOfPackets; i++, PacketArray++)
{
Status = CrystalSend( MiniportAdapterContext, *PacketArray, 0 );
NDIS_SET_PACKET_STATUS(*PacketArray, Status );
}
};
//****************************************************************************
// CrystalGetReturnedPacket(
//****************************************************************************
extern
VOID
CrystalGetReturnedPacket(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET pPacket
)
{
WORD index;
WORD *pW;
PCD pCD;
VPM_SetupMiniContext;
pCD = pChip->pData;
/* Reinitialize the NDIS packet for later use. */
//NdisReinitializePacket(pPacket);
pW=(WORD *)pPacket->MiniportReserved;
index=*pW;
AddAFreePakcetToQ(pChip, index);
pCD->numNdisPacketsIndicated--;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -