📄 main.c
字号:
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Novell Eagle 2000 driver
* FILE: ne2000/main.c
* PURPOSE: Driver entry point
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISIONS:
* CSH 27/08-2000 Created
*/
#include <roscfg.h>
#include <ne2000.h>
#include <debug.h>
NTSTATUS
#ifndef _MSC_VER
STDCALL
#endif
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
#ifdef DBG
/* See debug.h for debug/trace constants */
ULONG DebugTraceLevel = 0;
#endif /* DBG */
/* List of supported OIDs */
static ULONG MiniportOIDList[] = {
OID_GEN_SUPPORTED_LIST,
OID_GEN_HARDWARE_STATUS,
OID_GEN_MEDIA_SUPPORTED,
OID_GEN_MEDIA_IN_USE,
OID_GEN_MAXIMUM_LOOKAHEAD,
OID_GEN_MAXIMUM_FRAME_SIZE,
OID_GEN_LINK_SPEED,
OID_GEN_TRANSMIT_BUFFER_SPACE,
OID_GEN_RECEIVE_BUFFER_SPACE,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_VENDOR_ID,
OID_GEN_VENDOR_DESCRIPTION,
OID_GEN_VENDOR_DRIVER_VERSION,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_CURRENT_LOOKAHEAD,
OID_GEN_DRIVER_VERSION,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_PROTOCOL_OPTIONS,
OID_GEN_MAC_OPTIONS,
OID_GEN_MEDIA_CONNECT_STATUS,
OID_GEN_MAXIMUM_SEND_PACKETS,
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_CURRENT_ADDRESS,
OID_802_3_MULTICAST_LIST,
OID_802_3_MAXIMUM_LIST_SIZE,
OID_802_3_MAC_OPTIONS
};
DRIVER_INFORMATION DriverInfo = {0};
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
#if 0
static BOOLEAN MiniportCheckForHang(
IN NDIS_HANDLE MiniportAdapterContext)
/*
* FUNCTION: Examines if an adapter has hung
* ARGUMENTS:
* MiniportAdapterContext = Pointer to adapter context area
* RETURNS:
* TRUE if the adapter has hung, FALSE if not
*/
{
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
return FALSE;
}
#endif
static VOID STDCALL MiniportDisableInterrupt(
IN NDIS_HANDLE MiniportAdapterContext)
/*
* FUNCTION: Disables interrupts from an adapter
* ARGUMENTS:
* MiniportAdapterContext = Pointer to adapter context area
*/
{
NDIS_DbgPrint(MAX_TRACE, ("Called. (MiniportDisableInterrupt).\n"));
#ifndef NOCARD
NICDisableInterrupts((PNIC_ADAPTER)MiniportAdapterContext);
#endif
}
static VOID STDCALL MiniportEnableInterrupt(
IN NDIS_HANDLE MiniportAdapterContext)
/*
* FUNCTION: Enables interrupts from an adapter
* ARGUMENTS:
* MiniportAdapterContext = Pointer to adapter context area
*/
{
NDIS_DbgPrint(MAX_TRACE, ("Called. (MiniportEnableInterrupt).\n"));
#ifndef NOCARD
NICEnableInterrupts((PNIC_ADAPTER)MiniportAdapterContext);
#endif
}
static VOID STDCALL MiniportHalt(
IN NDIS_HANDLE MiniportAdapterContext)
/*
* FUNCTION: Deallocates resources for and halts an adapter
* ARGUMENTS:
* MiniportAdapterContext = Pointer to adapter context area
*/
{
PNIC_ADAPTER Adapter = (PNIC_ADAPTER)MiniportAdapterContext;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
#ifndef NOCARD
/* Stop the NIC */
NICStop(Adapter);
#endif
/* Wait for any DPCs to complete. FIXME: Use something else */
NdisStallExecution(250000);
if (Adapter->InterruptRegistered)
/* Deregister interrupt */
NdisMDeregisterInterrupt(&Adapter->Interrupt);
if (Adapter->IOPortRangeRegistered)
/* Deregister I/O port range */
NdisMDeregisterIoPortRange(
Adapter->MiniportAdapterHandle,
Adapter->IoBaseAddress,
0x20,
Adapter->IOBase);
/* Remove adapter from global adapter list */
if ((&Adapter->ListEntry)->Blink != NULL) {
RemoveEntryList(&Adapter->ListEntry);
}
/* Free adapter context area */
NdisFreeMemory(Adapter, sizeof(NIC_ADAPTER), 0);
}
static VOID STDCALL MiQueryResources(
OUT PNDIS_STATUS Status,
IN PNIC_ADAPTER Adapter,
IN NDIS_HANDLE WrapperConfigurationContext)
{
PNDIS_RESOURCE_LIST AssignedResources;
UINT BufferSize = 0;
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
int i;
NdisMQueryAdapterResources(Status,
WrapperConfigurationContext,
NULL,
&BufferSize);
if (*Status == NDIS_STATUS_SUCCESS)
return;
*Status = NdisAllocateMemory((PVOID)&AssignedResources,
BufferSize,
0,
HighestAcceptableMax);
if (*Status != NDIS_STATUS_SUCCESS)
return;
NdisMQueryAdapterResources(Status,
WrapperConfigurationContext,
AssignedResources,
&BufferSize);
if (*Status != NDIS_STATUS_SUCCESS)
return;
for (i = 0; i < AssignedResources->Count; i++)
{
Descriptor = AssignedResources->PartialDescriptors + i;
switch (Descriptor->Type)
{
case CmResourceTypeInterrupt:
Adapter->InterruptLevel = Descriptor->u.Interrupt.Level;
Adapter->InterruptVector = Descriptor->u.Interrupt.Vector;
break;
case CmResourceTypePort:
Adapter->IoBaseAddress = Descriptor->u.Port.Start.LowPart;
break;
}
}
}
static NDIS_STATUS STDCALL MiniportInitialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE WrapperConfigurationContext)
/*
* FUNCTION: Adapter initialization function
* ARGUMENTS:
* OpenErrorStatus = Address of buffer to place additional status information
* SelectedMediumIndex = Address of buffer to place selected medium index
* MediumArray = Pointer to an array of NDIS_MEDIUMs
* MediaArraySize = Number of elements in MediumArray
* MiniportAdapterHandle = Miniport adapter handle assigned by NDIS
* WrapperConfigurationContext = Handle used to identify configuration context
* RETURNS:
* Status of operation
*/
{
UINT i;
NDIS_STATUS Status;
PNIC_ADAPTER Adapter;
NDIS_DbgPrint(MAX_TRACE, ("Called (Adapter %X).\n", MiniportAdapterHandle));
/* Search for 802.3 media which is the only one we support */
for (i = 0; i < MediumArraySize; i++) {
if (MediumArray[i] == NdisMedium802_3)
break;
}
if (i == MediumArraySize) {
NDIS_DbgPrint(MIN_TRACE, ("No supported media.\n"));
return NDIS_STATUS_UNSUPPORTED_MEDIA;
}
*SelectedMediumIndex = i;
Status = NdisAllocateMemory((PVOID)&Adapter,
sizeof(NIC_ADAPTER),
0,
HighestAcceptableMax);
if (Status != NDIS_STATUS_SUCCESS) {
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return Status;
}
NdisZeroMemory(Adapter, sizeof(NIC_ADAPTER));
Adapter->MiniportAdapterHandle = MiniportAdapterHandle;
Adapter->IoBaseAddress = DRIVER_DEFAULT_IO_BASE_ADDRESS;
Adapter->InterruptLevel = DRIVER_DEFAULT_INTERRUPT_NUMBER;
Adapter->InterruptVector = DRIVER_DEFAULT_INTERRUPT_NUMBER;
Adapter->MaxMulticastListSize = DRIVER_MAX_MULTICAST_LIST_SIZE;
Adapter->InterruptMask = DRIVER_INTERRUPT_MASK;
Adapter->LookaheadSize = DRIVER_MAXIMUM_LOOKAHEAD;
/* Query the resources from PnP. */
MiQueryResources(&Status, Adapter, WrapperConfigurationContext);
/* Get the port, irq, and MAC address from registry if the PnP
failed. */
if (Status != NDIS_STATUS_SUCCESS)
{
PNDIS_CONFIGURATION_PARAMETER ConfigurationParameter;
NDIS_HANDLE ConfigurationHandle;
UNICODE_STRING Keyword;
UINT *RegNetworkAddress = 0;
UINT RegNetworkAddressLength = 0;
NdisOpenConfiguration(&Status, &ConfigurationHandle, WrapperConfigurationContext);
if (Status == NDIS_STATUS_SUCCESS)
{
NdisInitUnicodeString(&Keyword, L"Irq");
NdisReadConfiguration(&Status, &ConfigurationParameter, ConfigurationHandle, &Keyword, NdisParameterHexInteger);
if(Status == NDIS_STATUS_SUCCESS)
{
NDIS_DbgPrint(MID_TRACE,("NdisReadConfiguration for Irq returned successfully, irq 0x%x\n",
ConfigurationParameter->ParameterData.IntegerData));
Adapter->InterruptLevel =
Adapter->InterruptVector = ConfigurationParameter->ParameterData.IntegerData;
}
NdisInitUnicodeString(&Keyword, L"Port");
NdisReadConfiguration(&Status, &ConfigurationParameter, ConfigurationHandle, &Keyword, NdisParameterHexInteger);
if(Status == NDIS_STATUS_SUCCESS)
{
NDIS_DbgPrint(MID_TRACE,("NdisReadConfiguration for Port returned successfully, port 0x%x\n",
ConfigurationParameter->ParameterData.IntegerData));
Adapter->IoBaseAddress = ConfigurationParameter->ParameterData.IntegerData;
}
/* the returned copy of the data is owned by NDIS and will be released on NdisCloseConfiguration */
NdisReadNetworkAddress(&Status, (PVOID *)&RegNetworkAddress, &RegNetworkAddressLength, ConfigurationHandle);
if(Status == NDIS_STATUS_SUCCESS && RegNetworkAddressLength == DRIVER_LENGTH_OF_ADDRESS)
{
int i;
NDIS_DbgPrint(MID_TRACE,("NdisReadNetworkAddress returned successfully, address %x:%x:%x:%x:%x:%x\n",
RegNetworkAddress[0], RegNetworkAddress[1], RegNetworkAddress[2], RegNetworkAddress[3],
RegNetworkAddress[4], RegNetworkAddress[5]));
for(i = 0; i < DRIVER_LENGTH_OF_ADDRESS; i++)
Adapter->StationAddress[i] = RegNetworkAddress[i];
}
NdisCloseConfiguration(ConfigurationHandle);
}
else
{
NDIS_DbgPrint(MIN_TRACE,("NdisOpenConfiguration returned error 0x%x\n", Status));
}
}
/* find the nic */
if (!NICCheck(Adapter)) {
NDIS_DbgPrint(MID_TRACE, ("No adapter found at (0x%X).\n", Adapter->IoBaseAddress));
NdisFreeMemory(Adapter, sizeof(NIC_ADAPTER), 0);
return NDIS_STATUS_ADAPTER_NOT_FOUND;
} else
NDIS_DbgPrint(MID_TRACE, ("Adapter found at (0x%X).\n", Adapter->IoBaseAddress));
NdisMSetAttributes(
MiniportAdapterHandle,
(NDIS_HANDLE)Adapter,
FALSE,
NdisInterfaceIsa);
Status = NdisMRegisterIoPortRange(
(PVOID*)&Adapter->IOBase,
MiniportAdapterHandle,
Adapter->IoBaseAddress,
0x20);
if (Status != NDIS_STATUS_SUCCESS) {
NDIS_DbgPrint(MIN_TRACE, ("Cannot register port range. Status (0x%X).\n", Status));
MiniportHalt((NDIS_HANDLE)Adapter);
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -