📄 celan.c
字号:
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
0
);
DEBUGMSG(ZONE_INIT,
(TEXT("CELAN: X RegisterAdapter CardSetup -- Failed\r\n")));
RETAILMSG(1,(TEXT("CELAN: X RegisterAdapter CardSetup -- Failed\r\n")));
status = NDIS_STATUS_ADAPTER_NOT_FOUND;
goto fail3;
}
DEBUGMSG(ZONE_INIT,(TEXT("CELAN: O RegisterAdapter CardSetup -- Success\r\n")));
//
// Initialize the interrupt.
//
status = NdisMRegisterInterrupt(
&Adapter->Interrupt,
Adapter->MiniportAdapterHandle,
Adapter->InterruptNumber,
Adapter->InterruptNumber,
FALSE,
FALSE,
NdisInterruptLatched
);
if (status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_INIT,(TEXT("CELAN: NdisMRegisterInterrupt -- Failed\r\n")));
RETAILMSG(1,(TEXT("CELAN: NdisMRegisterInterrupt -- Failed(0x%x)\r\n"),status));
RETAILMSG(1,(TEXT("NdisInterruptNumber:0x%x\r\n"),Adapter->InterruptNumber));
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_INTERRUPT_CONNECT,
0
);
goto fail3;
}
DEBUGMSG(ZONE_INIT,(TEXT("CELAN:RegisterAdapter Interrupt Connected\r\n")));
// register a shutdown handler for this card
NdisMRegisterAdapterShutdownHandler(
Adapter->MiniportAdapterHandle, // miniport handle.
Adapter, // shutdown context.
CelanShutdown // shutdown handler.
);
//
// Start up the adapter.
//
CardStart(Adapter);
//
// Initialization completed successfully.
//
DEBUGMSG(ZONE_INIT, (TEXT("CELAN:RegisterAdapter OK\r\n")));
return(NDIS_STATUS_SUCCESS);
//
// Code to unwind what has already been set up when a part of
// initialization fails, which is jumped into at various
// points based on where the failure occured. Jumping to
// a higher-numbered failure point will execute the code
// for that block and all lower-numbered ones.
//
fail3:
//
// Take us out of the AdapterQueue.
//
if (CelanMiniportBlock.AdapterQueue == Adapter)
{
CelanMiniportBlock.AdapterQueue = Adapter->NextAdapter;
}
else
{
PCELAN_ADAPTER TmpAdapter = CelanMiniportBlock.AdapterQueue;
while (TmpAdapter->NextAdapter != Adapter)
{
TmpAdapter = TmpAdapter->NextAdapter;
}
TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
}
//
// We already enabled the interrupt on the card, so
// turn it off.
//
//NdisRawWritePortUchar(Adapter->IoPAddr+NIC_COMMAND, CR_STOP);
CardStop(Adapter);
fail2:
NdisMDeregisterIoPortRange(
Adapter->MiniportAdapterHandle,
(ULONG)Adapter->IoBaseAddr,
0x20,
(PVOID)Adapter->IoPAddr
);
return(status);
}
extern
VOID
CelanShutdown(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
CELANShutdown is called to shut down the adapter. We need to unblock any
threads which may be called in, and terminate any loops. This function is
called by the WinCE NDIS.DLL when a PCMCIA card removal is detected. At that
point, any access to the CELAN registers may return random data, as the bus
is floating.
Arguments:
MiniportAdapterContext - The context value that the Miniport returned
from CelanInitialize; actually as pointer to an CELAN_ADAPTER.
Return Value:
None.
--*/
{
PCELAN_ADAPTER Adapter;
Adapter = PCELAN_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
Adapter->ShuttingDown = TRUE;
//
// Shut down the chip. Note that the card may not be present, so this
// routine should not do anything that might hang.
//
CardStop(Adapter);
}
extern
VOID
CelanHalt(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
CELANHalt removes an adapter that was previously initialized.
Arguments:
MiniportAdapterContext - The context value that the Miniport returned
from CelanInitialize; actually as pointer to an CELAN_ADAPTER.
Return Value:
None.
--*/
{
PCELAN_ADAPTER Adapter;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+CELAN:Halt\r\n")));
Adapter = PCELAN_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
//
// Shut down the chip.
//
CardStop(Adapter);
//
// Disconnect the interrupt line.
//
NdisMDeregisterInterrupt(&Adapter->Interrupt);
//
// Pause, waiting for any DPC stuff to clear.
//
NdisStallExecution(250000);
NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle,
(ULONG)Adapter->IoBaseAddr,
0x20,
(PVOID)Adapter->IoPAddr
);
//
// Remove the adapter from the global queue of adapters.
//
if (CelanMiniportBlock.AdapterQueue == Adapter) {
CelanMiniportBlock.AdapterQueue = Adapter->NextAdapter;
} else {
PCELAN_ADAPTER TmpAdapter = CelanMiniportBlock.AdapterQueue;
while (TmpAdapter->NextAdapter != Adapter) {
TmpAdapter = TmpAdapter->NextAdapter;
}
TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
}
// was this the last NIC?
if ((CelanMiniportBlock.AdapterQueue == NULL) &&
(CelanMiniportBlock.NdisWrapperHandle)) {
NdisTerminateWrapper (CelanMiniportBlock.NdisWrapperHandle, NULL);
CelanMiniportBlock.NdisWrapperHandle = NULL;
}
//
// Free up the memory
//
NdisFreeMemory(Adapter, sizeof(CELAN_ADAPTER), 0);
DEBUGMSG(ZONE_FUNCTION, (TEXT("-CELAN:Halt\r\n")));
return;
}
NDIS_STATUS
CelanReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
The CELANReset request instructs the Miniport to issue a hardware reset
to the network adapter. The driver also resets its software state. See
the description of NdisMReset for a detailed description of this request.
Arguments:
AddressingReset - Does the adapter need the addressing information reloaded.
MiniportAdapterContext - Pointer to the adapter structure.
Return Value:
The function value is the status of the operation.
--*/
{
//
// Pointer to the adapter structure.
//
PCELAN_ADAPTER Adapter = (PCELAN_ADAPTER)MiniportAdapterContext;
//
// Temporary looping variable
//
// UINT i;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+CELAN:Reset\r\n")));
//
// Physically reset the card.
//
//for LAN91C96 Adapter->NicInterruptMask = IM_TX_INT | IM_RCV_INT | IM_RX_OVRN_INT;
Adapter->NicInterruptMask = IM_TX_INT | IM_RCV_INT | IM_RX_OVRN_INT | IM_MD_INT;//for LAN91C111
DEBUGMSG(ZONE_FUNCTION, (TEXT("-CELAN:Reset\r\n")));
return (CardReset(Adapter) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
}
NDIS_STATUS
CelanQueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
/*++
Routine Description:
The CELANQueryInformation process a Query request for
NDIS_OIDs that are specific about the Driver.
Arguments:
MiniportAdapterContext - a pointer to the adapter.
Oid - the NDIS_OID to process.
InformationBuffer - a pointer into the
NdisRequest->InformationBuffer into which store the result of the query.
InformationBufferLength - a pointer to the number of bytes left in the
InformationBuffer.
BytesWritten - a pointer to the number of bytes written into the
InformationBuffer.
BytesNeeded - If there is not enough room in the information buffer
then this will contain the number of bytes needed to complete the
request.
Return Value:
The function value is the status of the operation.
--*/
{
//
// Pointer to the adapter structure.
//
PCELAN_ADAPTER Adapter = (PCELAN_ADAPTER)MiniportAdapterContext;
//
// General Algorithm:
//
// Switch(Request)
// Get requested information
// Store results in a common variable.
// default:
// Try protocol query information
// If that fails, fail query.
//
// Copy result in common variable to result buffer.
// Finish processing
UINT BytesLeft = InformationBufferLength;
PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
NDIS_MEDIUM Medium = NdisMedium802_3;
//
// This variable holds result of query
//
ULONG GenericULong;
USHORT GenericUShort;
UCHAR GenericArray[6];
UINT MoveBytes = sizeof(ULONG);
PVOID MoveSource = (PVOID)(&GenericULong);
DEBUGMSG(ZONE_FUNCTION, (TEXT("+CELAN:QueryInformation[0x%x]\r\n"),Oid));
//
// 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_MAC_OPTIONS:
GenericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
NDIS_MAC_OPTION_NO_LOOPBACK
);
break;
case OID_GEN_SUPPORTED_LIST:
MoveSource = (PVOID)(CelanSupportedOids);
MoveBytes = sizeof(CelanSupportedOids);
break;
case OID_GEN_HARDWARE_STATUS:
HardwareStatus = NdisHardwareStatusReady;
MoveSource = (PVOID)(&HardwareStatus);
MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
break;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
MoveSource = (PVOID) (&Medium);
MoveBytes = sizeof(NDIS_MEDIUM);
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
GenericULong = CELAN_MAX_LOOKAHEAD;
break;
case OID_GEN_MAXIMUM_FRAME_SIZE:
GenericULong = (ULONG)(1514 - CELAN_HEADER_SIZE);
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
GenericULong = (ULONG)(1514);
break;
case OID_GEN_LINK_SPEED:
GenericULong = (ULONG)(100000);
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
GenericULong = (ULONG)2048;
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
GenericULong = (ULONG)2048;
break;
case OID_GEN_TRANSMIT_BLOCK_SIZE:
GenericULong = (ULONG)256;
break;
case OID_GEN_RECEIVE_BLOCK_SIZE:
GenericULong = (ULONG)(256);
break;
case OID_GEN_VENDOR_ID:
NdisMoveMemory(
(PVOID)&GenericULong,
Adapter->PermanentAddress,
3
);
GenericULong &= 0xFFFFFF00;
GenericULong |= 0x01;
MoveSource = (PVOID)(&GenericULong);
MoveBytes = sizeof(GenericULong);
break;
case OID_GEN_VENDOR_DESCRIPTION:
MoveSource = (PVOID)"Hitachi Card Engine.";
MoveBytes = 21;
break;
case OID_GEN_DRIVER_VERSION:
GenericUShort = ((USHORT)CELAN_NDIS_MAJOR_VERSION << 8) |
CELAN_NDIS_MINOR_VERSION;
MoveSource = (PVOID)(&GenericUShort);
MoveBytes = sizeof(GenericUShort);
break;
case OID_GEN_CURRENT_PACKET_FILTER: // add for NDISTEST err
GenericULong = (ULONG)(Adapter->PacketFilter);
break;
case OID_GEN_CURRENT_LOOKAHEAD:
GenericULong = (ULONG)(Adapter->MaxLookAhead);
break;
case OID_802_3_PERMANENT_ADDRESS:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -