📄 cs8900a.c
字号:
pEthernet->intLine,
pEthernet->intLine,
FALSE,
FALSE,
NdisInterruptLatched);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_INIT, (TEXT("CS8900A: NdisMRegisterInterrupt failed 0x%x\r\n"), Status));
NdisWriteErrorLogEntry(MiniportAdapterHandle, NDIS_ERROR_CODE_INTERRUPT_CONNECT, 0);
break;
}
pEthernet->CurrentState = NdisHardwareStatusReady;
pEthernet->MediaState = UpdateMediaConnectStatus(pEthernet, NdisMediaStateDisconnected);
}
else
{
Status = NDIS_STATUS_FAILURE;
}
} while(FALSE);
// clear all stale events on CS8900.
do
{
NdisRawReadPortUshort( (ULONG)&(g_pCS8900Reg->CS8900_ISQ), &InterruptEvent );
} while (InterruptEvent & REG_NUM_MASK);
// last thing done: enable the interrupt.
EnablePBCInterrupt();
if (ConfigHandle)
{
NdisCloseConfiguration(ConfigHandle);
}
if (Status == NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_INIT, (TEXT("CS8900A:Initialize succeeded\n")));
}
else
{
if(g_pCS8900Reg != NULL)
{
VirtualFree((void *) g_pCS8900Reg, 0, MEM_RELEASE);
g_pCS8900Reg = NULL;
}
if (pEthernet)
NdisFreeMemory(pEthernet, sizeof(cs8900_t), 0);
}
DEBUGMSG(ZONE_INIT, (TEXT("CS8900A: -Cs8900aInitialize\r\n")));
return Status;
}
//------------------------------------------------------------------------------
//
// Function: Cs8900aHalt
//
// This function is called when the driver is to remove itself.
//
// Parameters:
// MiniportAdapterContext
// [in] pointer to adapter.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
#pragma NDIS_PAGABLE_FUNCTION(Cs8900aHalt)
void Cs8900aHalt(IN NDIS_HANDLE MiniportAdapterContext)
{
pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aHalt\r\n")));
pEthernet->CurrentState = NdisHardwareStatusClosing;
// Disable interrupt
InterruptChip(pEthernet, FALSE);
NdisMDeregisterAdapterShutdownHandler(pEthernet->ndisAdapterHandle);
NdisMDeregisterInterrupt(&(pEthernet->interruptObj));
pEthernet->CurrentState = NdisHardwareStatusNotReady;
if(g_pCS8900Reg != NULL)
{
VirtualFree((void *) g_pCS8900Reg, 0, MEM_RELEASE);
g_pCS8900Reg = NULL;
}
NdisFreeMemory( (PVOID)pEthernet, (UINT)sizeof(cs8900_t), 0);
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -Cs8900aHalt\r\n")));
return;
}
//------------------------------------------------------------------------------
//
// Function: Cs8900aQueryInformation
//
// This function handles a query operation for a single OID.
//
// Parameters:
// MiniportAdapterContext
// [in] pointer to adapter.
//
// Oid
// [out] The OID of the query.
//
// InformationBuffer
// [in] Holds the result of the query.
//
// InformationBufferLength
// [in] Length of InformationBuffer.
//
// BytesWritten
// [out] If the call is successful, returns the number of bytes written
// to InformationBuffer.
//
// BytesNeeded
// [out] If there is not enough room in InformationBuffer to satisfy the OID,
// returns the amount of storage needed.
//
// Returns:
// Returns NDIS_STATUS_SUCCESS if success.
// Return NDIS_STATUS_INVALID_LENGTH or NDIS_STATUS_INVALID_OID if not.
//
//------------------------------------------------------------------------------
NDIS_STATUS
Cs8900aQueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
{
NDIS_STATUS result = NDIS_STATUS_SUCCESS;
UINT BytesLeft = InformationBufferLength;
PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
// This variable holds result of query
ULONG GenericULong;
USHORT GenericUShort;
UCHAR GenericArray[6];
UINT MoveBytes = sizeof(ULONG);
PVOID MoveSource = (PVOID)(&GenericULong);
pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aQueryInformation\r\n")));
// Make sure that int is 4 bytes. Else GenericULong must change
// to something of size 4.
ASSERT(sizeof(ULONG) == 4);
// Switch on request type
switch(Oid)
{
case OID_GEN_VENDOR_DRIVER_VERSION:
GenericULong = (CS8900A_NDIS_MAJOR_VERSION << 16) + CS8900A_NDIS_MINOR_VERSION;
break;
case OID_GEN_SUPPORTED_LIST:
MoveSource = (PVOID)(Cs8900aSupportedOids);
MoveBytes = sizeof(Cs8900aSupportedOids);
break;
case OID_GEN_HARDWARE_STATUS:
GenericULong = pEthernet->CurrentState;
break;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
GenericULong = NdisMedium802_3;
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
GenericULong = UpdateMediaConnectStatus(pEthernet, pEthernet->MediaState);
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
GenericULong = ETH_MAX_PACKET -ETHER_HDR_SIZE ;
break;
case OID_GEN_MAXIMUM_FRAME_SIZE:
GenericULong = ETH_MAX_PACKET -ETHER_HDR_SIZE ;
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
GenericULong = ETH_MAX_PACKET;
break;
case OID_GEN_MAC_OPTIONS:
GenericULong = (ULONG)(
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
NDIS_MAC_OPTION_NO_LOOPBACK
);
break;
case OID_GEN_LINK_SPEED:
GenericULong = 100000; // 10 Mbps in 100 bps units
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
GenericULong = MAXIMUM_TRANSMIT_PACKET * ETH_MAX_PACKET;
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
GenericULong = ETH_MAX_PACKET;
break;
case OID_GEN_TRANSMIT_BLOCK_SIZE:
GenericULong = ETH_MAX_PACKET;
break;
case OID_GEN_RECEIVE_BLOCK_SIZE:
GenericULong = ETH_MAX_PACKET;
break;
case OID_GEN_VENDOR_DESCRIPTION:
MoveSource = (PVOID)"Crystal LAN(tm) CS8900 Ethernet Adapter";
MoveBytes = 40;
break;
case OID_GEN_VENDOR_ID:
NdisMoveMemory((PVOID)&GenericULong,
&(pEthernet->PermanentAddress),
(ULONG)ETHER_ADDR_SIZE);
GenericULong &= 0xFFFFFF00;
GenericULong |= 0x01;
MoveSource = (PVOID)(&GenericULong);
MoveBytes = sizeof(GenericULong);
break;
case OID_GEN_DRIVER_VERSION:
GenericUShort = ((USHORT)CS8900A_NDIS_MAJOR_VERSION << 8) |
CS8900A_NDIS_MINOR_VERSION;
MoveSource = (PVOID)(&GenericUShort);
MoveBytes = sizeof(GenericUShort);
break;
case OID_GEN_CURRENT_PACKET_FILTER:
GenericULong = (ULONG)(pEthernet->PacketFilter);
break;
case OID_GEN_CURRENT_LOOKAHEAD:
GenericULong = (ULONG)(pEthernet->CurrentLookAhead);
break;
case OID_GEN_XMIT_OK:
GenericULong = (UINT)(pEthernet->FramesXmitGood);
break;
case OID_GEN_RCV_OK:
GenericULong = (UINT)(pEthernet->FramesRcvGood);
break;
case OID_GEN_XMIT_ERROR:
GenericULong = (UINT)(pEthernet->FramesXmitBad);
break;
case OID_GEN_RCV_ERROR:
GenericULong = (UINT)(pEthernet->RcvErrors);
break;
case OID_GEN_RCV_NO_BUFFER:
GenericULong = (UINT)(pEthernet->MissedPackets);
break;
case OID_802_3_PERMANENT_ADDRESS:
NdisMoveMemory((PCHAR)GenericArray,
pEthernet->PermanentAddress,
(ULONG)ETHER_ADDR_SIZE);
MoveSource = (PVOID)(GenericArray);
MoveBytes = sizeof(pEthernet->PermanentAddress);
break;
case OID_802_3_CURRENT_ADDRESS:
NdisMoveMemory((PCHAR)GenericArray,
pEthernet->CurrentAddress,
(ULONG)ETHER_ADDR_SIZE);
MoveSource = (PVOID)(GenericArray);
MoveBytes = sizeof(pEthernet->CurrentAddress);
break;
case OID_802_3_MULTICAST_LIST:
MoveSource = (PVOID)(pEthernet->McastList);
MoveBytes = pEthernet->NumMulticastAddressesInUse * ETHER_ADDR_SIZE;
break;
case OID_802_3_MAXIMUM_LIST_SIZE:
GenericULong = MCAST_LIST_SIZE;
break;
case OID_802_3_RCV_ERROR_ALIGNMENT:
GenericULong = (UINT)(pEthernet->FrameAlignmentErrors);
break;
case OID_802_3_XMIT_ONE_COLLISION:
GenericULong = (UINT)(pEthernet->FramesXmitOneCollision);
break;
case OID_802_3_XMIT_MORE_COLLISIONS:
GenericULong = (UINT)(pEthernet->FramesXmitManyCollisions);
break;
case OID_GEN_MAXIMUM_SEND_PACKETS:
GenericULong = (UINT)(pEthernet->TxMaxCount);
break;
case OID_GEN_RCV_CRC_ERROR:
GenericULong = (UINT)(pEthernet->RcvCRCErrors);
break;
case OID_GEN_TRANSMIT_QUEUE_LENGTH:
GenericULong = 0L;
break;
case OID_802_3_XMIT_MAX_COLLISIONS:
GenericULong = (UINT)(pEthernet->XmitMaxCollisions);
break;
case OID_802_3_RCV_OVERRUN:
GenericULong = (UINT)(pEthernet->RcvOverrun);
break;
case OID_802_3_XMIT_UNDERRUN:
GenericULong = (UINT)(pEthernet->XmitUnderrun);
break;
default:
result = NDIS_STATUS_INVALID_OID;
break;
}
if (result == NDIS_STATUS_SUCCESS)
{
if (MoveBytes > BytesLeft)
{
// Not enough room in InformationBuffer.
*BytesNeeded = MoveBytes;
result = NDIS_STATUS_INVALID_LENGTH;
}
else
{
// Store result.
NdisMoveMemory(InfoBuffer, MoveSource, MoveBytes);
*BytesWritten = MoveBytes;
}
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -Cs8900aQueryInformation\r\n")));
return result;
}
//------------------------------------------------------------------------------
//
// Function: Cs8900aReset
//
// The function instructs the driver to issue a hardware reset to the network adapter.
// The driver also resets its software state. See the description of MiniportMReset
// for a detailed description of this request.
// No hardware function call to soft reset adapter as it will fail the CETK test in WINCE 4.2.
//
// Parameters:
// AddressingReset
// [out] Does the adapter need the addressing information reloaded?
//
// MiniportAdapterContext
// [in] pointer to adapter.
//
// Returns:
// Returns NDIS_STATUS_SUCCESS if success.
//
//------------------------------------------------------------------------------
NDIS_STATUS
Cs8900aReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
)
{
PNDIS_PACKET pNdisPacket;
pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aReset\r\n")));
pEthernet->CurrentState = NdisHardwareStatusReset;
// Disable interrupt at the chip
InterruptChip(pEthernet, FALSE);
pEthernet->TransmitInProgress = FALSE;
pEthernet->StartTX = FALSE;
pEthernet->TransmitBidPending = FALSE;
//
// Remove the packet from the queue.
//
EnterCriticalSection (&gCS8900BufCs);
pNdisPacket = pEthernet->HeadPacket;
while(pNdisPacket != NULL)
{
pEthernet->HeadPacket = RESERVED(pNdisPacket)->Next;
if (pNdisPacket == pEthernet->TailPacket)
{
pEthernet->TailPacket = NULL;
}
NdisMSendComplete(pEthernet->ndisAdapterHandle, pNdisPacket, NDIS_STATUS_SUCCESS);
pNdisPacket = pEthernet->HeadPacket;
}
LeaveCriticalSection (&gCS8900BufCs);
*AddressingReset = TRUE;
pEthernet->CurrentState = NdisHardwareStatusReady;
// Enable interrupt at the chip
InterruptChip(pEthernet, TRUE);
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -Cs8900aReset\r\n")));
return NDIS_STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -