?? smsc111.c
字號:
// Get MAC address
//
datasize = sizeof(DWORD);
if ( RegQueryValueEx(hKey, TEXT("MAC0"), NULL, &kvaluetype,
(LPBYTE)&MacValue,&datasize) )
{
DEBUGMSG (ZONE_INIT | ZONE_ERROR,
(TEXT("Faild to get MAC0 value.\r\n")));
//return STATUS_UNSUCCESSFUL;
MAC0 = 0; // for ROM
}
else
MAC0 = (WORD)MacValue;
datasize = sizeof(DWORD);
if ( RegQueryValueEx(hKey, TEXT("MAC1"), NULL, &kvaluetype,
(LPBYTE)&MacValue,&datasize) )
{
DEBUGMSG (ZONE_INIT | ZONE_ERROR,
(TEXT("Faild to get MAC1 value.\r\n")));
//return STATUS_UNSUCCESSFUL;
MAC1 = 0; // for ROM
}
else
MAC1 = (WORD)MacValue;
datasize = sizeof(DWORD);
if ( RegQueryValueEx(hKey, TEXT("MAC2"), NULL, &kvaluetype,
(LPBYTE)&MacValue,&datasize) )
{
DEBUGMSG (ZONE_INIT | ZONE_ERROR,
(TEXT("Faild to get MAC2 value.\r\n")));
//return STATUS_UNSUCCESSFUL;
MAC2 = 0; // for ROM
}
else
MAC2 = (WORD)MacValue;
//
// Read any registry settings (currently nonthing to read)
//
RegCloseKey (hKey);
DEBUGMSG (ZONE_INIT,(TEXT("LAN91C111 register base address : %x\r\n"),RegisterBase));
//
// Save the global information about this driver.
//
gSmsc111MiniportBlock.AdapterQueue = (PSMSC111_ADAPTER)NULL;
//
// Initialize the Miniport characteristics for the call to
// NdisMRegisterMiniport.
//
memset (&Characteristics, 0, sizeof (Characteristics));
Characteristics.MajorNdisVersion = SMSC111_NDIS_MAJOR_VERSION;
Characteristics.MinorNdisVersion = SMSC111_NDIS_MINOR_VERSION;
Characteristics.CheckForHangHandler = NULL;
Characteristics.DisableInterruptHandler = Smsc111DisableInterrupt;
Characteristics.EnableInterruptHandler = Smsc111EnableInterrupt;
Characteristics.HaltHandler = Smsc111Halt;
Characteristics.HandleInterruptHandler = Smsc111HandleInterrupt;
Characteristics.InitializeHandler = Smsc111Initialize;
Characteristics.ISRHandler = Smsc111Isr;
Characteristics.QueryInformationHandler = Smsc111QueryInformation;
Characteristics.ReconfigureHandler = NULL;
Characteristics.ResetHandler = Smsc111Reset;
Characteristics.SendHandler = Smsc111Send;
Characteristics.SetInformationHandler = Smsc111SetInformation;
Characteristics.TransferDataHandler = NULL;
Characteristics.ReturnPacketHandler = NULL;
Characteristics.SendPacketsHandler = NULL;
Characteristics.AllocateCompleteHandler = NULL;
Status = NdisMRegisterMiniport (gSmsc111MiniportBlock.NdisWrapperHandle, &Characteristics, sizeof (Characteristics));
if (Status == NDIS_STATUS_SUCCESS)
{
DEBUGMSG (ZONE_INIT | ZONE_FUNCTION, (TEXT (" CELAN:DriverEntry: Success\r\n")));
Status = STATUS_SUCCESS;
}
else
{
// Terminate the wrapper.
NdisTerminateWrapper (gSmsc111MiniportBlock.NdisWrapperHandle, NULL);
gSmsc111MiniportBlock.NdisWrapperHandle = NULL;
Status = STATUS_UNSUCCESSFUL;
DEBUGMSG (ZONE_INIT | ZONE_FUNCTION, (TEXT ("!CELAN:DriverEntry: Unsuccessful\r\n")));
}
DEBUGMSG (ZONE_INIT | ZONE_FUNCTION, (TEXT ("-CELAN:DriverEntry\r\n")));
// NKDbgPrintfW (L"-CELAN: DriverEntry\r\n");
return (Status);
}
/*
* Description:
* The Smsc111Reset 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:
* pbAddressingReset - Does the adapter need the addressing information reloaded.
* hMiniportAdapterContext - Pointer to the adapter structure.
*
* Return Value:
* The status of the operation.
*/
NDIS_STATUS
Smsc111Reset (OUT PBOOLEAN pbAddressingReset, IN NDIS_HANDLE hMiniportAdapterContext)
{
BOOLEAN bResult;
//
// Pointer to the adapter structure.
//
PSMSC111_ADAPTER pAdapter = (PSMSC111_ADAPTER)(hMiniportAdapterContext);
DEBUGMSG (ZONE_FUNCTION, (TEXT ("+CELAN: Reset\r\n")));
//
// Physically reset the card.
//
pAdapter->usNicInterruptMask = IM_TX_INT | IM_RCV_INT | IM_RX_OVRN_INT | IM_EPH_INT;
DEBUGMSG (ZONE_FUNCTION, (TEXT ("-CELAN: Reset\r\n")));
bResult = CardReset (pAdapter);
if (bResult)
return (NDIS_STATUS_SUCCESS);
return (NDIS_STATUS_FAILURE);
}
/*
* This routine is used to turn on the interrupt mask.
*
* Arguments:
* Context - The adapter for the SMSC111 to enable.
*
* Return Value:
* None.
*/
VOID
Smsc111EnableInterrupt (IN NDIS_HANDLE hMiniportAdapterContext)
{
PSMSC111_ADAPTER pAdapter = (PSMSC111_ADAPTER)(hMiniportAdapterContext);
DEBUGMSG (ZONE_INTR, (TEXT ("+CELAN: EnableInterrupt\r\n")));
CardUnblockInterrupts (pAdapter);
DEBUGMSG(ZONE_INTR, (TEXT ("-CELAN: EnableInterrupt\r\n")));
}
/*
* Description:
* This routine is used to turn off the interrupt mask.
*
* Arguments:
* Context - The adapter for the SMSC111 to disable.
*
* Return Value:
* None.
*/
VOID
Smsc111DisableInterrupt (IN NDIS_HANDLE hMiniportAdapterContext)
{
PSMSC111_ADAPTER pAdapter = (PSMSC111_ADAPTER)(hMiniportAdapterContext);
DEBUGMSG (ZONE_INTR, (TEXT ("+CELAN:DisableInterrupt\r\n")));
CardBlockInterrupts (pAdapter);
DEBUGMSG(ZONE_INTR, (TEXT ("-CELAN:DisableInterrupt\r\n")));
}
/*
* Description:
* Smsc111Halt removes an adapter that was previously initialized.
*
* Arguments:
* hMiniportAdapterContext - The context value that the Miniport returned from Smsc111Initialize.
*
* Return Value:
* None.
*/
VOID
Smsc111Halt (IN NDIS_HANDLE hMiniportAdapterContext)
{
PSMSC111_ADAPTER pAdapter = (PSMSC111_ADAPTER)(hMiniportAdapterContext);
DEBUGMSG (ZONE_FUNCTION, (TEXT ("+CELAN: Halt\r\n")));
//
// Shut down the chip.
//
CardStop (pAdapter);
//
// Disconnect the interrupt line.
//
NdisMDeregisterInterrupt (&pAdapter->Interrupt);
//
// Pause, waiting for any DPC stuff to clear.
//
NdisMSleep (250000);
//
// Remove the adapter from the global queue of adapters.
//
if (gSmsc111MiniportBlock.AdapterQueue == pAdapter)
gSmsc111MiniportBlock.AdapterQueue = pAdapter->NextAdapter;
else
{
PSMSC111_ADAPTER TmpAdapter = gSmsc111MiniportBlock.AdapterQueue;
while (TmpAdapter->NextAdapter != pAdapter)
TmpAdapter = TmpAdapter->NextAdapter;
TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
}
//
// Was this the last NIC?
//
if ((gSmsc111MiniportBlock.AdapterQueue == NULL) && gSmsc111MiniportBlock.NdisWrapperHandle)
{
NdisTerminateWrapper (gSmsc111MiniportBlock.NdisWrapperHandle, NULL);
gSmsc111MiniportBlock.NdisWrapperHandle = NULL;
}
//
// If the initial VirtualAlloc was successful, then free the allocated memory.
//
if (pAdapter->pVirtualRegisterBase)
VirtualFree ((PVOID)(pAdapter->pVirtualRegisterBase), 0, MEM_RELEASE);
//
// Free up the memory
//
NdisFreeMemory (pAdapter, sizeof (PSMSC111_ADAPTER), 0);
DEBUGMSG (ZONE_FUNCTION, (TEXT ("-CELAN: Halt\r\n")));
return;
}
/*
* Description:
* Smsc111Initialize starts an adapter and registers resources with the wrapper.
*
* Arguments:
* OpenErrorStatus - Extra status bytes for opening token ring adapters.
* puiSelectedMediumIndex - Pointer to index of the media type chosen by the driver.
* MediumArray - Array of media types for the driver to chose from.
* uiMediumArraySize - Number of entries in the array.
* hMiniportAdapterHandle - Handle for passing to the wrapper when referring to this adapter.
* hConfigurationHandle - A handle to pass to NdisOpenConfiguration.
*
* Return Value:
* NDIS_STATUS_SUCCESS
* NDIS_STATUS_PENDING
* NDIS_STATUS_UNSUPPORTED_MEDIA
*/
#pragma NDIS_PAGEABLE_FUNCTION (Smsc111Initialize)
NDIS_STATUS
Smsc111Initialize (OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT puiSelectedMediumIndex, IN PNDIS_MEDIUM MediumArray, IN UINT uiMediumArraySize, IN NDIS_HANDLE hMiniportAdapterHandle, IN NDIS_HANDLE hConfigurationHandle)
{
PSMSC111_ADAPTER pAdapter; // Pointer to our newly allocated adapter.
NDIS_HANDLE hConfigHandle; // The handle for reading from the registry.
BOOLEAN bConfigError = FALSE; // TRUE if there is a configuration error.
ULONG ulConfigErrorValue = 0; // A special value to log concerning the error.
//UCHAR ucInterruptNumber; // The interrupt number to use.
UINT uiIndex; // Temporary looping variable.
NDIS_STATUS Status; // Status of Ndis calls.
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
NDIS_STRING IOAddressStr = IOADDRESS;
NDIS_STRING InterruptStr = INTERRUPT;
NDIS_STRING IOMultiplier = IOMULTIPLIER;
DEBUGMSG (ZONE_FUNCTION, (TEXT ("+CELAN: Initialize\r\n")));
// NKDbgPrintfW (L"+CELAN: Initialize\r\n");
//
// Search for the medium type (802.3) in the given array.
//
for (uiIndex = 0; uiIndex < uiMediumArraySize; uiIndex++)
{
if (MediumArray[uiIndex] == NdisMedium802_3)
break;
}
if (uiIndex == uiMediumArraySize)
{
DEBUGMSG (ZONE_INIT | ZONE_ERROR, (TEXT ("!CELAN: Initialize: No supported media\r\n")));
return (NDIS_STATUS_UNSUPPORTED_MEDIA);
}
*puiSelectedMediumIndex = uiIndex;
DEBUGMSG (ZONE_INIT, (TEXT (" CELAN: Selected media is %d.\r\n"), *puiSelectedMediumIndex));
//
// Set default values.
//
//ucInterruptNumber = SMSC111Irq;
//
// Allocate memory for the adapter block now.
//
Status = NdisAllocateMemory ((PVOID *)&pAdapter, sizeof (SMSC111_ADAPTER), 0, HighestAcceptableMax);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG (ZONE_INIT | ZONE_ERROR, (TEXT ("!CELAN: Initialize: NdisAllocateMemory (SMSC111_ADAPTER) failed.\r\n")));
return (Status);
}
DEBUGMSG (ZONE_INIT | ZONE_ERROR, (TEXT (" CELAN: Initialize: pAdapter allocated at 0x%x.\r\n"), pAdapter));
// NKDbgPrintfW (L" CELAN: Initialize: pAdapter allocated at 0x%x.\r\n", pAdapter);
//
// Clear out the adapter block, which sets all default values to FALSE, or NULL.
//
NdisZeroMemory (pAdapter, sizeof (SMSC111_ADAPTER));
//
// Open the configuration space.
//
NdisOpenConfiguration (&Status, &hConfigHandle, hConfigurationHandle);
if (Status != NDIS_STATUS_SUCCESS) {
NdisFreeMemory (pAdapter, sizeof (SMSC111_ADAPTER), 0);
DEBUGMSG (ZONE_INIT, (TEXT ("!CELAN: Initialize: NdisOpenConfiguration failed 0x%x\r\n"), Status));
return (Status);
}
NdisReadConfiguration(
&Status,
&ReturnedValue,
hConfigHandle,
&IOMultiplier,
NdisParameterHexInteger
);
if (Status == NDIS_STATUS_SUCCESS) {
pAdapter->uMultiplier= (ReturnedValue->ParameterData.IntegerData);
}
else
pAdapter->uMultiplier=1;// Default
//
// Read I/O Address
//
NdisReadConfiguration(
&Status,
&ReturnedValue,
hConfigHandle,
&IOAddressStr,
NdisParameterHexInteger
);
if (Status == NDIS_STATUS_SUCCESS) {
pAdapter->ulIoBaseAddress= (ReturnedValue->ParameterData.IntegerData);
NdisReadConfiguration(
&Status,
&ReturnedValue,
hConfigHandle,
&InterruptStr,
NdisParameterInteger
);
if (Status == NDIS_STATUS_SUCCESS) {
pAdapter->ucInterruptNumber= (CCHAR)(ReturnedValue->ParameterData.IntegerData);
}
}
DEBUGMSG (ZONE_INIT, (TEXT (" CELAN: IO address 0x%lx, Interrupt number 0x%lx, io multiplier=0x%lx\r\n"),
pAdapter->ulIoBaseAddress,pAdapter->ucInterruptNumber,pAdapter->uMultiplier));
//
// First close the configuration space.
//
NdisCloseConfiguration (hConfigHandle);
if (Status !=NDIS_STATUS_SUCCESS) {
NdisFreeMemory (pAdapter, sizeof (SMSC111_ADAPTER), 0);
DEBUGMSG (ZONE_INIT, (TEXT ("!CELAN: Initialize: NdisReadCOnfiguration failed 0x%x\r\n"), Status));
return Status;
}
//
// Set up the parameters.
//
// pAdapter->ucInterruptNumber = ucInterruptNumber;
pAdapter->hMiniportAdapterHandle = hMiniportAdapterHandle;
pAdapter->ulMaxLookAhead = MAX_LOOKAHEAD;
//
// Now do the work.
//
if (Smsc111RegisterAdapter (pAdapter, hConfigurationHandle, bConfigError, ulConfigErrorValue) != NDIS_STATUS_SUCCESS) {
//
// Smsc111RegisterAdapter failed.
//
NdisFreeMemory (pAdapter, sizeof (SMSC111_ADAPTER), 0);
DEBUGMSG (ZONE_INIT, (TEXT ("!CELAN: NdisRegisterAdapter failed.\r\n")));
return (NDIS_STATUS_FAILURE);
}
DEBUGMSG (ZONE_INIT, (TEXT (" CELAN: Initialize succeeded\r\n")));
DEBUGMSG (ZONE_FUNCTION, (TEXT ("-CELAN: Initialize\r\n")));
// Dump all the registers before coming out.
printregs(pAdapter);
printregs(pAdapter);
// NKDbgPrintfW (L"-CELAN: Initialize\r\n");
return (NDIS_STATUS_SUCCESS);
}
/*
* Description:
* Called when a new adapter should be registered. It allocates space for
* the adapter, initializes the adapter's block, registers resources
* with the wrapper and initializes the physical adapter.
*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -