summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/aic5900/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/ndis/aic5900/init.c')
-rw-r--r--private/ntos/ndis/aic5900/init.c1534
1 files changed, 1534 insertions, 0 deletions
diff --git a/private/ntos/ndis/aic5900/init.c b/private/ntos/ndis/aic5900/init.c
new file mode 100644
index 000000000..5c497d026
--- /dev/null
+++ b/private/ntos/ndis/aic5900/init.c
@@ -0,0 +1,1534 @@
+/*++
+
+Copyright (c) 1990-1995 Microsoft Corporation
+
+Module Name:
+
+ D:\nt\private\ntos\ndis\aic5900\init.c
+
+Abstract:
+
+Author:
+
+ Kyle Brandon (KyleB)
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+#include "aic5900.h"
+
+#define MODULE_NUMBER MODULE_INIT
+
+#pragma NDIS_INIT_FUNCTION(DriverEntry)
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ NDIS_STATUS Status;
+ NDIS_MINIPORT_CHARACTERISTICS Aic5900Chars;
+ NDIS_HANDLE hWrapper;
+
+ //
+ // Initialize the wrapper.
+ //
+ NdisMInitializeWrapper(
+ &hWrapper,
+ DriverObject,
+ RegistryPath,
+ NULL);
+
+ NdisZeroMemory(&Aic5900Chars, sizeof(Aic5900Chars));
+
+ //
+ // Initialize the miniport characteristics.
+ //
+ Aic5900Chars.MajorNdisVersion = AIC5900_NDIS_MAJOR_VERSION;
+ Aic5900Chars.MinorNdisVersion = AIC5900_NDIS_MINOR_VERSION;
+ Aic5900Chars.CheckForHangHandler = Aic5900CheckForHang;
+ Aic5900Chars.DisableInterruptHandler = Aic5900DisableInterrupt;
+ Aic5900Chars.EnableInterruptHandler = Aic5900EnableInterrupt;
+ Aic5900Chars.HaltHandler = Aic5900Halt;
+ Aic5900Chars.HandleInterruptHandler = Aic5900HandleInterrupt;
+ Aic5900Chars.InitializeHandler = Aic5900Initialize;
+ Aic5900Chars.ISRHandler = Aic5900ISR;
+ Aic5900Chars.ReconfigureHandler = NULL;
+ Aic5900Chars.ResetHandler = Aic5900Reset;
+
+ Aic5900Chars.ReturnPacketHandler = Aic5900ReturnPackets;
+ Aic5900Chars.AllocateCompleteHandler = Aic5900AllocateComplete;
+ Aic5900Chars.SetInformationHandler = Aic5900SetInformation;
+ Aic5900Chars.QueryInformationHandler = Aic5900QueryInformation;
+
+ Aic5900Chars.CoSendPacketsHandler = Aic5900SendPackets;
+
+ Aic5900Chars.CoCreateVcHandler = Aic5900CreateVc;
+ Aic5900Chars.CoDeleteVcHandler = Aic5900DeleteVc;
+ Aic5900Chars.CoActivateVcHandler = Aic5900ActivateVc;
+ Aic5900Chars.CoDeactivateVcHandler = Aic5900DeactivateVc;
+ Aic5900Chars.CoRequestHandler = Aic5900Request;
+
+ //
+ // Register the miniport with NDIS.
+ //
+ Status = NdisMRegisterMiniport(
+ hWrapper,
+ &Aic5900Chars,
+ sizeof(Aic5900Chars));
+ if (NDIS_STATUS_SUCCESS == Status)
+ {
+ //
+ // Save the handle to the wrapper.
+ //
+ gWrapperHandle = hWrapper;
+ }
+#if DBG
+ else
+ {
+ DbgPrint("NdisMRegisterMiniport failed! Status: 0x%x\n", Status);
+ }
+#endif
+
+
+ return(Status);
+}
+
+
+NDIS_STATUS
+aic5900ReadConfigurationInformation(
+ IN NDIS_HANDLE ConfigurationHandle,
+ IN PAIC5900_REGISTRY_PARAMETER pRegistryParameter
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ NDIS_STATUS Status;
+ NDIS_HANDLE ConfigHandle;
+ PNDIS_CONFIGURATION_PARAMETER pConfigParameter;
+ UINT c;
+
+ //
+ // Open the configuration section of the registry for this adapter.
+ //
+ NdisOpenConfiguration(&Status, &ConfigHandle, ConfigurationHandle);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Unable to open the Aic5900's Parameters registry key\n"));
+
+ return(Status);
+ }
+
+ //
+ // Read in the registry parameters.
+ //
+ for (c = 0; c < Aic5900MaxRegistryEntry; c++)
+ {
+ NdisReadConfiguration(
+ &Status,
+ &pConfigParameter,
+ ConfigHandle,
+ &gaRegistryParameterString[c],
+ NdisParameterHexInteger);
+ if (NDIS_STATUS_SUCCESS == Status)
+ {
+ pRegistryParameter[c].fPresent = TRUE;
+ pRegistryParameter[c].Value = pConfigParameter->ParameterData.IntegerData;
+
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
+ ("Read registry parameter: %u = 0x%x\n", c, pRegistryParameter[c].Value));
+ }
+
+ }
+
+ //
+ // Close the configuration handle.
+ //
+ NdisCloseConfiguration(ConfigHandle);
+
+ return(NDIS_STATUS_SUCCESS);
+}
+
+NDIS_STATUS
+aic5900ReadPciConfiguration(
+ IN PADAPTER_BLOCK pAdapter
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ PPCI_COMMON_CONFIG PciCommonConfig;
+ PHARDWARE_INFO pHwInfo = pAdapter->HardwareInfo;
+ PNDIS_RESOURCE_LIST ResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource;
+ NDIS_STATUS Status;
+ UINT c;
+ UINT Temp;
+
+ //
+ // Allocate memory for the pci common config space.
+ //
+ ALLOCATE_MEMORY(
+ &Status,
+ &pHwInfo->PciCommonConfig,
+ PCI_COMMON_HDR_LENGTH);
+ if (NULL == pHwInfo->PciCommonConfig)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("aic5900ReadPciConfiguration() failed to allocate memory for PCI Common Config.\n"));
+
+ return(NDIS_STATUS_RESOURCES);
+ }
+
+ PciCommonConfig = pHwInfo->PciCommonConfig;
+
+ //
+ // Read the board id. This is a combination of the vendor id and
+ // the device id.
+ //
+ Temp = NdisReadPciSlotInformation(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->SlotNumber,
+ 0,
+ PciCommonConfig,
+ PCI_COMMON_HDR_LENGTH);
+ if (Temp != PCI_COMMON_HDR_LENGTH)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Unable to read PCI configuration header\n"));
+
+ return(NDIS_STATUS_FAILURE);
+ }
+
+ //
+ // Verify vendor & device id's.
+ //
+ if ((ADAPTEC_PCI_VENDOR_ID != PciCommonConfig->VendorID) ||
+ (AIC5900_PCI_DEVICE_ID != PciCommonConfig->DeviceID))
+ {
+ return(NDIS_STATUS_FAILURE);
+ }
+
+ //
+ // Set the command word in pci space.
+ //
+ PciCommonConfig->Command = PCI_ENABLE_MEMORY_SPACE |
+ PCI_ENABLE_BUS_MASTER |
+ PCI_ENABLE_WRITE_AND_INVALIDATE |
+ PCI_ENABLE_SERR;
+
+ NdisWritePciSlotInformation(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->SlotNumber,
+ FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
+ &PciCommonConfig->Command,
+ sizeof(PciCommonConfig->Command));
+
+ NdisReadPciSlotInformation(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->SlotNumber,
+ 0,
+ PciCommonConfig,
+ PCI_COMMON_HDR_LENGTH);
+
+ PciCommonConfig->u.type0.BaseAddresses[0] &= 0xFFFFFFF0;
+
+ //
+ // For noisy debug dump what we find in the PCI space.
+ //
+ dbgDumpPciCommonConfig(PciCommonConfig);
+
+ //
+ // Assign the pci resources.
+ //
+ Status = NdisMPciAssignResources(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->SlotNumber,
+ &ResourceList);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("NdisMPciAssignResoures() failed: 0x%x\n", Status));
+
+ return(Status);
+ }
+
+ //
+ // Walk the resource list to get the adapters configuration
+ // information.
+ //
+ for (c = 0; c < ResourceList->Count; c++)
+ {
+ Resource = &ResourceList->PartialDescriptors[c];
+ switch (Resource->Type)
+ {
+ case CmResourceTypeInterrupt:
+ //
+ // Save the interrupt number with our adapter block.
+ //
+ pHwInfo->InterruptLevel = Resource->u.Interrupt.Level;
+ pHwInfo->InterruptVector = Resource->u.Interrupt.Vector;
+
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
+ ("Configured to use interrupt Level: %u interrupt vector: %u\n", pHwInfo->InterruptLevel, pHwInfo->InterruptVector));
+
+ break;
+
+ case CmResourceTypeMemory:
+
+ //
+ // Save the memory mapped base physical address and it's length.
+ //
+ pHwInfo->PhysicalIoSpace = Resource->u.Memory.Start;
+ pHwInfo->IoSpaceLength = Resource->u.Memory.Length;
+
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
+ ("Configured to use mapped memory memory 0x%x:0x%x of length 0x%x\n",
+ NdisGetPhysicalAddressHigh(pHwInfo->PhysicalIoSpace),
+ NdisGetPhysicalAddressLow(pHwInfo->PhysicalIoSpace),
+ pHwInfo->IoSpaceLength));
+
+ break;
+
+ case CmResourceTypePort:
+
+ //
+ // Save the port.
+ //
+ pHwInfo->InitialPort = NdisGetPhysicalAddressLow(Resource->u.Port.Start);
+ pHwInfo->NumberOfPorts = Resource->u.Port.Length;
+
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
+ ("Configured to use port memory 0x%x of length 0x%x\n",
+ pHwInfo->InitialPort,
+ pHwInfo->NumberOfPorts));
+
+ break;
+ }
+ }
+
+ return(NDIS_STATUS_SUCCESS);
+}
+
+NDIS_STATUS
+aic5900GetNicModelNumberFromString(
+ IN PHARDWARE_INFO pHwInfo
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ ULONG NicModel;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+ AIC_ULONG_TO_ULONG(&NicModel, (PULONG)(&pHwInfo->FCodeImage->Model[5]));
+
+ //
+ // Compare the second DWORD in the NicModelString
+ //
+ switch (NicModel)
+ {
+ case '5910':
+ pHwInfo->NicModelNumber = ANA_5910;
+
+ //
+ // This is a 25Mbps adapter and has a 16MHz cell clock.
+ //
+ pHwInfo->CellClockRate = CELL_CLOCK_16MHZ;
+
+ break;
+
+ case '5930':
+ pHwInfo->NicModelNumber = ANA_5930;
+
+ //
+ // This is a 155Mbps adapter and has a 25MHz cell clock.
+ //
+ pHwInfo->CellClockRate = CELL_CLOCK_25MHZ;
+
+ break;
+
+ case '5940':
+ pHwInfo->NicModelNumber = ANA_5940;
+
+ //
+ // This is a 155Mbps adapter and has a 25MHz cell clock.
+ //
+ pHwInfo->CellClockRate = CELL_CLOCK_25MHZ;
+
+ break;
+
+ default:
+
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Invalid NIC Model String!\n"));
+
+ pHwInfo->NicModelNumber = ANA_INVALID;
+
+ Status = NDIS_STATUS_FAILURE;
+ break;
+ }
+
+ return(Status);
+}
+
+
+NDIS_STATUS
+aic5900ReadEepromInformation(
+ IN PADAPTER_BLOCK pAdapter
+ )
+/*++
+
+Routine Description:
+
+ This routine will map the EEPROM address into memory and read the offsets for the other
+ information that will be needed.
+
+Arguments:
+
+ pAdapter - Pointer to the adapter block to save the information.
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS if everthing went ok.
+ NDIS_STATUS_FAILURE otherwise.
+
+--*/
+{
+ NDIS_PHYSICAL_ADDRESS PhysicalAddress;
+ NDIS_STATUS Status;
+ PHARDWARE_INFO pHwInfo;
+
+ PPCI_FCODE_IMAGE pFCode;
+ PPCI_FCODE_IMAGE pFCodeImage;
+
+ PUCHAR EepromBase = NULL;
+ UCHAR HighByte;
+ UCHAR LowByte;
+
+ USHORT FCodeImageOffset;
+ ULONG FCodeName;
+
+ do
+ {
+ //
+ // Initialize the hardware info.
+ //
+ pHwInfo = pAdapter->HardwareInfo;
+
+ //
+ // Map the first part of the EEPROM to read the
+ // configuration information.
+ //
+ PhysicalAddress = pHwInfo->PhysicalIoSpace;
+
+ Status = NdisMMapIoSpace(
+ &EepromBase,
+ pAdapter->MiniportAdapterHandle,
+ PhysicalAddress,
+ FCODE_SIZE);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to map the PCI FCode I/O space into memory\n"));
+ break;
+ }
+
+ //
+ // Get the offset to the Fcode image.
+ //
+ EEPROM_READ_UCHAR(EepromBase + 3, &HighByte);
+ EEPROM_READ_UCHAR(EepromBase + 2, &LowByte);
+ FCodeImageOffset = (USHORT)((HighByte << 8) + LowByte);
+
+ if (0xFFFF == FCodeImageOffset)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Invalid data read from the EEPROM.\n"));
+ Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
+ break;
+ }
+
+ pFCode = (PPCI_FCODE_IMAGE)(EepromBase + FCodeImageOffset);
+
+ ALLOCATE_MEMORY(&Status, &pHwInfo->FCodeImage, FCODE_SIZE);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to allocate memory for the eeprom image\n"));
+ break;
+ }
+
+ EEPROM_READ_BUFFER(pHwInfo->FCodeImage, pFCode, FCODE_SIZE);
+
+ pFCodeImage = pHwInfo->FCodeImage;
+
+ //
+ // For debug this will get dumped.
+ //
+ dbgDumpPciFCodeImage(pFCodeImage);
+
+ //
+ // Check the name parameter in the fcode image.
+ // We add 1 since this name is in PASCAL format (the first byte
+ // is the length of the string)....
+ //
+ AIC_ULONG_TO_ULONG(&FCodeName, (PULONG)(&pFCodeImage->Name[1]));
+ if (FCodeName != FCODE_NAME)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Invalid name in FCode Image\n"));
+
+ Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Get the model number for the NIC.
+ //
+ Status = aic5900GetNicModelNumberFromString(pHwInfo);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
+ break;
+ }
+
+ //
+ // Get the ROM version number.
+ //
+ AIC_ULONG_TO_ULONG(&pHwInfo->RomVersionNumber, &pFCodeImage->RomVersionNumber);
+
+ //
+ // Get EPROM offset and size and map in.
+ //
+ AIC_ULONG_TO_ULONG(&pHwInfo->rEpromOffset, &pFCodeImage->roEpromOffset);
+ AIC_ULONG_TO_ULONG(&pHwInfo->rEpromSize, &pFCodeImage->roEpromSize);
+
+ NdisSetPhysicalAddressLow(
+ PhysicalAddress,
+ NdisGetPhysicalAddressLow(pHwInfo->PhysicalIoSpace) +
+ pHwInfo->rEpromOffset);
+
+ Status = NdisMMapIoSpace(
+ &pHwInfo->rEprom,
+ pAdapter->MiniportAdapterHandle,
+ PhysicalAddress,
+ pHwInfo->rEpromSize);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ break;
+ }
+
+ //
+ // Get R/W EPROM offset and size and map in.
+ //
+ AIC_ULONG_TO_ULONG(&pHwInfo->rwEpromOffset, &pFCodeImage->rwEpromOffset);
+ AIC_ULONG_TO_ULONG(&pHwInfo->rwEpromSize, &pFCodeImage->rwEpromSize);
+
+ NdisSetPhysicalAddressLow(
+ PhysicalAddress,
+ NdisGetPhysicalAddressLow(pHwInfo->PhysicalIoSpace) +
+ pHwInfo->rwEpromOffset);
+
+ Status = NdisMMapIoSpace(
+ &pHwInfo->rwEprom,
+ pAdapter->MiniportAdapterHandle,
+ PhysicalAddress,
+ pHwInfo->rwEpromSize);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ break;
+ }
+
+ //
+ // Get PHY offset and size and map in.
+ //
+ AIC_ULONG_TO_ULONG(&pHwInfo->PhyOffset, &pFCodeImage->PhyOffset);
+ AIC_ULONG_TO_ULONG(&pHwInfo->PhySize, &pFCodeImage->PhySize);
+
+ NdisSetPhysicalAddressLow(
+ PhysicalAddress,
+ NdisGetPhysicalAddressLow(pHwInfo->PhysicalIoSpace) +
+ pHwInfo->PhyOffset);
+
+ Status = NdisMMapIoSpace(
+ (PVOID *)&pHwInfo->Phy,
+ pAdapter->MiniportAdapterHandle,
+ PhysicalAddress,
+ pHwInfo->PhySize);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ break;
+ }
+
+ //
+ // Get EXTERNAL offset and size and map in.
+ //
+ AIC_ULONG_TO_ULONG(&pHwInfo->ExternalOffset, &pFCodeImage->ExternalOffset);
+ AIC_ULONG_TO_ULONG(&pHwInfo->ExternalSize, &pFCodeImage->ExternalSize);
+
+ NdisSetPhysicalAddressLow(
+ PhysicalAddress,
+ NdisGetPhysicalAddressLow(pHwInfo->PhysicalIoSpace) +
+ pHwInfo->ExternalOffset);
+
+ Status = NdisMMapIoSpace(
+ &pHwInfo->External,
+ pAdapter->MiniportAdapterHandle,
+ PhysicalAddress,
+ pHwInfo->ExternalSize);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ break;
+ }
+
+ //
+ // Get SAR offset and size and map in.
+ //
+ AIC_ULONG_TO_ULONG(&pHwInfo->MidwayOffset, &pFCodeImage->SarOffset);
+ AIC_ULONG_TO_ULONG(&pHwInfo->MidwaySize, &pFCodeImage->SarSize);
+
+ NdisSetPhysicalAddressLow(
+ PhysicalAddress,
+ NdisGetPhysicalAddressLow(pHwInfo->PhysicalIoSpace) +
+ pHwInfo->MidwayOffset);
+
+ Status = NdisMMapIoSpace(
+ (PVOID *)&pHwInfo->Midway,
+ pAdapter->MiniportAdapterHandle,
+ PhysicalAddress,
+ pHwInfo->MidwaySize);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ break;
+ }
+
+ //
+ // Get PCI Config offset and size and map in.
+ //
+ AIC_ULONG_TO_ULONG(&pHwInfo->PciCfgOffset, &pFCodeImage->PciConfigOffset);
+ AIC_ULONG_TO_ULONG(&pHwInfo->PciCfgSize, &pFCodeImage->PciConfigSize);
+
+ NdisSetPhysicalAddressLow(
+ PhysicalAddress,
+ NdisGetPhysicalAddressLow(pHwInfo->PhysicalIoSpace) +
+ pHwInfo->PciCfgOffset);
+
+ Status = NdisMMapIoSpace(
+ (PVOID *)&pHwInfo->PciConfigSpace,
+ pAdapter->MiniportAdapterHandle,
+ PhysicalAddress,
+ pHwInfo->PciCfgSize);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ break;
+ }
+
+ //
+ // Get SAR RAM offset and size and map in.
+ //
+ AIC_ULONG_TO_ULONG(&pHwInfo->SarRamOffset, &pFCodeImage->SarMemOffset);
+ AIC_ULONG_TO_ULONG(&pHwInfo->SarRamSize, &pFCodeImage->SarMemSize);
+
+ NdisSetPhysicalAddressLow(
+ PhysicalAddress,
+ NdisGetPhysicalAddressLow(pHwInfo->PhysicalIoSpace) +
+ pHwInfo->SarRamOffset);
+
+ Status = NdisMMapIoSpace(
+ (PVOID *)&pHwInfo->SarRam,
+ pAdapter->MiniportAdapterHandle,
+ PhysicalAddress,
+ pHwInfo->SarRamSize);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ break;
+ }
+
+ //
+ // Read in the manufacturer address for the nic.
+ //
+ EEPROM_READ_BUFFER(
+ pHwInfo->PermanentAddress,
+ (((PUCHAR)pHwInfo->rEprom) + pHwInfo->rEpromSize) - sizeof(EEPROM_MANUFACTURER_INFO),
+ ATM_ADDRESS_LENGTH);
+
+ //
+ // Save the permanent address in the station address by default.
+ //
+ NdisMoveMemory(
+ pHwInfo->StationAddress,
+ pHwInfo->PermanentAddress,
+ ATM_ADDRESS_LENGTH);
+
+ dbgDumpHardwareInformation(pHwInfo);
+ } while (FALSE);
+
+ if (EepromBase != NULL)
+ {
+ NdisMUnmapIoSpace(
+ pAdapter->MiniportAdapterHandle,
+ (PVOID)EepromBase,
+ FCODE_SIZE);
+ }
+
+ return(Status);
+}
+
+VOID
+aic5900FreeResources(
+ IN PADAPTER_BLOCK pAdapter
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ PHARDWARE_INFO pHwInfo;
+ PVC_BLOCK pVc;
+ PLIST_ENTRY Link;
+
+ if (NULL != pAdapter)
+ {
+ if (NULL != pAdapter->HardwareInfo)
+ {
+ pHwInfo = pAdapter->HardwareInfo;
+
+ if (NULL != pHwInfo->PciCommonConfig)
+ {
+ FREE_MEMORY(pHwInfo->PciCommonConfig, PCI_COMMON_HDR_LENGTH);
+ }
+
+ if (NULL != pHwInfo->PortOffset)
+ {
+ NdisMDeregisterIoPortRange(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->InitialPort,
+ pHwInfo->NumberOfPorts,
+ pHwInfo->PortOffset);
+ }
+
+ if (NULL != pHwInfo->rEprom)
+ {
+ NdisMUnmapIoSpace(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->rEprom,
+ pHwInfo->rEpromSize);
+ }
+
+ if (NULL != pHwInfo->rwEprom)
+ {
+ NdisMUnmapIoSpace(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->rwEprom,
+ pHwInfo->rwEpromSize);
+ }
+
+ if (NULL != pHwInfo->Phy)
+ {
+ NdisMUnmapIoSpace(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->Phy,
+ pHwInfo->PhySize);
+ }
+
+ if (NULL != pHwInfo->External)
+ {
+ NdisMUnmapIoSpace(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->External,
+ pHwInfo->ExternalSize);
+ }
+
+ if (NULL != pHwInfo->Midway)
+ {
+ NdisMUnmapIoSpace(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->Midway,
+ pHwInfo->MidwaySize);
+ }
+
+ if (NULL != pHwInfo->PciConfigSpace)
+ {
+ NdisMUnmapIoSpace(
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->PciConfigSpace,
+ pHwInfo->PciCfgSize);
+ }
+
+ if (NULL != pHwInfo->SarRam)
+ {
+ NdisMUnmapIoSpace(
+ pAdapter->MiniportAdapterHandle,
+ (PVOID)pHwInfo->SarRam,
+ pHwInfo->SarRamSize);
+ }
+
+ if (NULL != pHwInfo->FCodeImage)
+ {
+ FREE_MEMORY(pHwInfo->FCodeImage, FCODE_SIZE);
+ }
+
+ if (HW_TEST_FLAG(pHwInfo, fHARDWARE_INFO_INTERRUPT_REGISTERED))
+ {
+ NdisMDeregisterInterrupt(&pHwInfo->Interrupt);
+ }
+
+ //
+ // Free the spin lock for the hardware information.
+ //
+ NdisFreeSpinLock(&pHwInfo->Lock);
+
+ //
+ // Free the memory used for the hardware information.
+ //
+ FREE_MEMORY(pHwInfo, sizeof(HARDWARE_INFO));
+ }
+
+ ///
+ // Clean up our list of active VCs.
+ ///
+ while (!IsListEmpty(&pAdapter->ActiveVcList))
+ {
+ //
+ // Remove the VC from the list, deactivate it and delete it.
+ //
+ Link = RemoveHeadList(&pAdapter->ActiveVcList);
+ pVc = CONTAINING_RECORD(Link, VC_BLOCK, Link);
+ Aic5900DeactivateVc((NDIS_HANDLE)pVc);
+ Aic5900DeleteVc((NDIS_HANDLE)pVc);
+ }
+
+ //
+ // Walk our list of inactive VCs.
+ //
+ while (!IsListEmpty(&pAdapter->InactiveVcList))
+ {
+ //
+ // Remove the VC from the list and delete it.
+ //
+ Link = RemoveHeadList(&pAdapter->InactiveVcList);
+ pVc = CONTAINING_RECORD(Link, VC_BLOCK, Link);
+ Aic5900DeleteVc((NDIS_HANDLE)pVc);
+ }
+
+ //
+ // Free up the spin lock for the adapter block.
+ //
+ NdisFreeSpinLock(&pAdapter->Lock);
+
+ //
+ // Free the memory allocated for the adapter block.
+ //
+ FREE_MEMORY(pAdapter, sizeof(ADAPTER_BLOCK));
+ }
+}
+
+
+NDIS_STATUS
+aic5900InitPciRegisters(
+ IN PADAPTER_BLOCK pAdapter
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ PHARDWARE_INFO pHwInfo = pAdapter->HardwareInfo;
+ PCI_DEVICE_CONFIG regConfig;
+ PCI_DEVICE_ENABLE_PCI_INTERRUPT regEnableInt;
+ PCI_DEVICE_DMA_CONTROL regDmaControl;
+
+ //
+ // Reset the ORION
+ //
+ GET_PCI_DEV_CFG(pHwInfo, &regConfig);
+ regConfig.SoftwareReset = 1;
+ SET_PCI_DEV_CFG(pHwInfo, regConfig.reg);
+
+ //
+ // Program the interrupt enable register.
+ //
+ GET_PCI_DEV_ENABLE_INT(pHwInfo, &regEnableInt);
+ regEnableInt.EnableDpeInt = 0;
+ regEnableInt.EnableSseInt = 1;
+ regEnableInt.EnableStaInt = 1;
+ regEnableInt.EnableRmaInt = 1;
+ regEnableInt.EnableRtaInt = 1;
+ regEnableInt.EnableDprInt = 1;
+ SET_PCI_DEV_ENABLE_INT(pHwInfo, regEnableInt.reg);
+
+ //
+ // Program the PCI device config register.
+ //
+ GET_PCI_DEV_CFG(pHwInfo, &regConfig);
+ regConfig.MasterSwapBytes = 1;
+ regConfig.EnableInterrupt = 1;
+ SET_PCI_DEV_CFG(pHwInfo, regConfig.reg);
+
+ //
+ // Program the DMA control register.
+ //
+ GET_PCI_DEV_DMA_CONTROL(pHwInfo, &regDmaControl);
+ regDmaControl.CacheThresholdEnable = 1;
+ SET_PCI_DEV_DMA_CONTROL(pHwInfo, regDmaControl.reg);
+
+ return(NDIS_STATUS_SUCCESS);
+}
+
+NDIS_STATUS
+aic5900InitPhyRegisters(
+ IN PADAPTER_BLOCK pAdapter
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ PHARDWARE_INFO pHwInfo = pAdapter->HardwareInfo;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+ switch (pAdapter->HardwareInfo->NicModelNumber)
+ {
+ case ANA_5910:
+
+ //
+ // Reset the IBM TC and PDM chips. The host can reset TC
+ // and PDM chips by first writing a word to the Software Reset
+ // register and then reading it back.
+ //
+ // Reset clears the STATUS register and flushes the TC receive
+ // FIFO.
+ //
+ SET_IBM_TC_SOFTWARE_RESET(pHwInfo, 0);
+
+ //
+ // Enable TC overrun and cell error interrupts.
+ //
+ SET_IBM_TC_MASK(pHwInfo, 0x04);
+
+ break;
+
+ case ANA_5940:
+ case ANA_5930:
+
+ //
+ // Set and clear the reset bit for the phy.
+ //
+ SET_SUNI_MASTER_RESET_IDEN(pHwInfo, fSUNI_MRI_RESET);
+ SET_SUNI_MASTER_RESET_IDEN(pHwInfo, 0);
+
+ //
+ // Clear the SUNI test mode.
+ //
+ SET_SUNI_MASTER_TEST(pHwInfo, 0);
+
+ //
+ // Enable SUNI RACP interrupts.
+ //
+ SET_SUNI_RACP_INT_ENABLE_STATUS(pHwInfo, (fSUNI_RACP_IES_FIFOE | fSUNI_RACP_IES_HCSE));
+
+ break;
+
+ default:
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
+ ("aic5900InitPhyRegisters: Unknown adapter model 0x%x\n", pAdapter->HardwareInfo->NicModelNumber));
+
+ Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
+
+ break;
+ }
+
+ return(Status);
+}
+
+NDIS_STATUS
+aic5900InitSarRegisters(
+ IN PADAPTER_BLOCK pAdapter
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ PSAR_INFO pSar;
+ PHARDWARE_INFO pHwInfo = pAdapter->HardwareInfo;
+ PXMIT_SEG_CHANNEL pCurrent;
+ ULONG RamOffset;
+ UINT c;
+
+ do
+ {
+ //
+ // Allocate memory for the sar.
+ //
+ ALLOCATE_MEMORY(&Status, &pSar, sizeof(SAR_INFO));
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ break;
+ }
+
+ ZERO_MEMORY(pSar, sizeof(SAR_INFO));
+
+ NdisAllocateSpinLock(&pSar->lockFreeXmitSegment);
+
+ //
+ // Initialize the VCI table, DMA receive and transmit queues,
+ // the service list, and everything else in the SAR ram.
+ //
+ for (c = 0; c < pHwInfo->SarRamSize / 4; c++)
+ {
+ NdisWriteRegisterUlong(pHwInfo->SarRam + c, 0);
+ }
+
+ //
+ // Initialize the memory manager for our sar ram....
+ //
+ Status = Aic5900InitializeRamInfo(&pHwInfo->hRamInfo, pHwInfo->SarRamSize);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Unable to initialize the memory manager for the adapter memory\n"));
+
+ break;
+ }
+
+ //
+ // Allocate memory for the VCI table.
+ // NOTE:
+ // We don't need to save the ram offset since this is always
+ // at offset 0.
+ //
+ Status = Aic5900AllocateRam(
+ &RamOffset,
+ pHwInfo->hRamInfo,
+ sizeof(MIDWAY_VCI_TABLE_ENTRY) * MAX_VCS);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
+ ("Unable to allocate the VCI table in adapter ram\n"));
+
+ break;
+ }
+
+ ASSERT(MIDWAY_VCI_TABLE_OFFSET == RamOffset);
+
+ //
+ // Allocate memory for the receive DMA queue.
+ // NOTE:
+ // We don't need to save the RAM offset since this is always at
+ // offset 0x4000.
+ //
+ Status = Aic5900AllocateRam(
+ &RamOffset,
+ pHwInfo->hRamInfo,
+ sizeof(MIDWAY_DMA_DESC) * MIDWAY_DMA_QUEUE_SIZE);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Unable to allocate the receive queue from the adapter ram\n"));
+
+ break;
+ }
+
+ ASSERT(MIDWAY_RECEIVE_DMA_QUEUE_OFFSET == RamOffset);
+
+ //
+ // Allocate memory for the transmit DMA queue.
+ // NOTE:
+ // We don't need to save the RAM offset since this is always at
+ // offset 0x5000.
+ //
+ Status = Aic5900AllocateRam(
+ &RamOffset,
+ pHwInfo->hRamInfo,
+ sizeof(MIDWAY_DMA_DESC) * MIDWAY_DMA_QUEUE_SIZE);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Unable to allocate the transmit queue from the adapter ram\n"));
+
+ break;
+ }
+
+ ASSERT(MIDWAY_TRANSMIT_DMA_QUEUE_OFFSET == RamOffset);
+
+ //
+ // Allocate memory for the service queue.
+ // NOTE:
+ // We don't need to save the RAM offset since this is always at
+ // offset 0x6000.
+ //
+ Status = Aic5900AllocateRam(
+ &RamOffset,
+ pHwInfo->hRamInfo,
+ sizeof(MIDWAY_SERVICE_LIST) * MIDWAY_SERVICE_QUEUE_SIZE);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Unable to allocate the service queue\n"));
+
+ break;
+ }
+
+ ASSERT(MIDWAY_SERVICE_QUEUE_OFFSET == RamOffset);
+
+ //
+ // Get a block of nic ram for the transmit channel.
+ //
+ Status = Aic5900AllocateRam(&RamOffset, pHwInfo->hRamInfo, BLOCK_16K);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Unable to allocate adapter memory for the UBR channel\n"));
+
+ break;
+ }
+
+ //
+ // Setup the UBR (best effort) channel.
+ //
+ pCurrent = &pSar->XmitSegChannel[0];
+ pSar->ubrXmitChannel = pCurrent;
+
+ NdisZeroMemory(pCurrent, sizeof(XMIT_SEG_CHANNEL));
+
+ NdisAllocateSpinLock(&pCurrent->lock);
+ pCurrent->Adapter = pAdapter;
+ pCurrent->MidwayChannelNumber = MIDWAY_XMIT_SEG_CHANNEL_UBR;
+
+ pCurrent->MidwayInitRegs.XmitPlace.Size =
+ CONVERT_BYTE_SIZE_TO_MIDWAY_SIZE(BLOCK_16K / 4);
+ pCurrent->MidwayInitRegs.XmitPlace.Location =
+ CONVERT_BYTE_OFFSET_TO_MIDWAY_LOCATION(RamOffset);
+ pCurrent->MidwayInitRegs.XmitReadPointer.Register = 0;
+ pCurrent->MidwayInitRegs.XmitDescriptorStart.Register = 0;
+
+ pCurrent->MidwayTransmitRegs =
+ &pHwInfo->Midway->TransmitRegisters[MIDWAY_XMIT_SEG_CHANNEL_UBR];
+
+ pCurrent->SegmentSize = BLOCK_SIZE_16k / 4;
+ pCurrent->Segment = (HWUL *)&pHwInfo->SarRam[RamOffset / 4];
+ pCurrent->SegmentReadPointer = 0;
+ pCurrent->SegmentWritePointer = 0;
+ pCurrent->SegmentRoom = BLOCK_SIZE_16k / 4;
+ pCurrent->XmitPduBytes = 0;
+
+ InitializeListHead(&pCurrent->SegmentWaitQ);
+ InitializeListHead(&pCurrent->TransmitWaitQ);
+
+ for (c = 1, pCurrent = &pSar->XmitSegChannel[c];
+ c < MIDWAY_MAX_SEGMENT_CHANNELS;
+ c++, pCurrent++)
+ {
+ NdisZeroMemory(pCurrent, sizeof(XMIT_SEG_CHANNEL));
+ NdisAllocateSpinLock(&pCurrent->lock);
+
+ pCurrent->Adapter = pAdapter;
+ pCurrent->MidwayChannelNumber = c;
+
+ //
+ // Place the segment channel on the free queue.
+ //
+ pCurrent->Next = pSar->FreeXmitSegChannel;
+ pSar->FreeXmitSegChannel = pCurrent;
+
+ //
+ // Get a pointer to the midway transmit registers.
+ //
+ pCurrent->MidwayTransmitRegs =
+ &pHwInfo->Midway->TransmitRegisters[c];
+
+ //
+ // Initialize the queues.
+ //
+ InitializeListHead(&pCurrent->SegmentWaitQ);
+ InitializeListHead(&pCurrent->TransmitWaitQ);
+ }
+
+ //
+ // Initialize the Midway Master Control register.
+ //
+ pSar->MidwayMasterControl = (MID_REG_MC_S_DMA_ENABLE |
+ MID_REG_MC_S_XMT_ENABLE |
+ MID_REG_MC_S_RCV_ENABLE |
+ MID_REG_MC_S_XMT_LOCK_MODE);
+ pHwInfo->Midway->MCS = pSar->MidwayMasterControl;
+
+ //
+ // Initialize the UBR transmit channel.
+ //
+ pHwInfo->Midway->TransmitRegisters[MIDWAY_XMIT_SEG_CHANNEL_UBR].XmitPlace.Register =
+ pSar->ubrXmitChannel->MidwayInitRegs.XmitPlace.Register;
+
+ pHwInfo->Midway->TransmitRegisters[MIDWAY_XMIT_SEG_CHANNEL_UBR].XmitReadPointer.Register =
+ pSar->ubrXmitChannel->MidwayInitRegs.XmitReadPointer.Register;
+
+ pHwInfo->Midway->TransmitRegisters[MIDWAY_XMIT_SEG_CHANNEL_UBR].XmitDescriptorStart.Register =
+ pSar->ubrXmitChannel->MidwayInitRegs.XmitDescriptorStart.Register;
+
+ pHwInfo->InterruptMask = MID_REG_INT_PCI |
+ MID_REG_INT_XMT_COMPLETE_7 |
+ MID_REG_INT_XMT_COMPLETE_6 |
+ MID_REG_INT_XMT_COMPLETE_5 |
+ MID_REG_INT_XMT_COMPLETE_4 |
+ MID_REG_INT_XMT_COMPLETE_3 |
+ MID_REG_INT_XMT_COMPLETE_2 |
+ MID_REG_INT_XMT_COMPLETE_1 |
+ MID_REG_INT_XMT_COMPLETE_0 |
+ MID_REG_INT_XMT_DMA_OVFL |
+ MID_REG_INT_XMT_IDEN_MISMTCH |
+ MID_REG_INT_DMA_ERR_ACK |
+ MID_REG_INT_RCV_DMA_COMPLETE |
+ MID_REG_INT_XMT_DMA_COMPLETE |
+ MID_REG_INT_SERVICE |
+ MID_REG_INT_SUNI_INT;
+
+ pHwInfo->Midway->IE = pHwInfo->InterruptMask;
+
+ Status = NDIS_STATUS_SUCCESS;
+ } while (FALSE);
+
+ //
+ // If we failed somewhere above then we need to cleanup....
+ //
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ if (NULL != pHwInfo->hRamInfo)
+ {
+ Aic5900UnloadRamInfo(pHwInfo->hRamInfo);
+ }
+
+ if (NULL != pSar)
+ {
+ NdisFreeSpinLock(&pSar->lockFreeXmitSegment);
+ FREE_MEMORY(pSar, sizeof(SAR_INFO));
+ }
+ }
+
+ return(Status);
+}
+
+
+NDIS_STATUS
+Aic5900Initialize(
+ OUT PNDIS_STATUS OpenErrorStatus,
+ OUT PUINT SelectedMediumIndex,
+ IN PNDIS_MEDIUM MediumArray,
+ IN UINT MediumArraySize,
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN NDIS_HANDLE ConfigurationHandle
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+{
+ UINT c;
+ PADAPTER_BLOCK pAdapter;
+ PHARDWARE_INFO pHwInfo;
+ NDIS_STATUS Status;
+ PAIC5900_REGISTRY_PARAMETER pRegistryParameter;
+
+ do
+ {
+ //
+ // Initialize for clean-up.
+ //
+ pAdapter = NULL;
+
+ //
+ // Do we support any of the given media types?
+ //
+ for (c = 0; c < MediumArraySize; c++)
+ {
+ if (MediumArray[c] == NdisMediumAtm)
+ {
+ break;
+ }
+ }
+
+ //
+ // If we went through the whole media list without finding
+ // a supported media type let the wrapper know.
+ //
+ if (c == MediumArraySize)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Media not supported by version of ndis\n"));
+
+ Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
+
+ break;
+ }
+
+ *SelectedMediumIndex = c;
+
+ //
+ // Allocate memory for the registry parameters.
+ //
+ ALLOCATE_MEMORY(
+ &Status,
+ &pRegistryParameter,
+ sizeof(AIC5900_REGISTRY_PARAMETER) * Aic5900MaxRegistryEntry);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_COMP_ERR,
+ ("Unable to allocate memroy for the registry parameters\n"));
+
+ break;
+ }
+
+ ZERO_MEMORY(
+ pRegistryParameter,
+ sizeof(AIC5900_REGISTRY_PARAMETER) * Aic5900MaxRegistryEntry);
+
+ //
+ // Fill in some default registry values.
+ //
+ pRegistryParameter[Aic5900VcHashTableSize].Value = 13;
+
+ //
+ // Read our parameters out of the registry.
+ //
+ Status = aic5900ReadConfigurationInformation(
+ pRegistryParameter,
+ ConfigurationHandle);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to read the configuration information from the registry\n"));
+
+ break;
+ }
+
+ //
+ // Allocate memory for our adapter block and initialize it.
+ //
+ ALLOCATE_MEMORY(
+ &Status,
+ &pAdapter,
+ sizeof(ADAPTER_BLOCK) +
+ (pRegistryParameter[Aic5900VcHashTableSize].Value * sizeof(ULONG)));
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to allocate memory for the adapter block\n"));
+ break;
+ }
+
+ ZERO_MEMORY(pAdapter, sizeof(ADAPTER_BLOCK));
+
+ pAdapter->MiniportAdapterHandle = MiniportAdapterHandle;
+
+ NdisAllocateSpinLock(&pAdapter->Lock);
+
+ //
+ // Spin lock and other odd allocations/initializations.
+ //
+ InitializeListHead(&pAdapter->ActiveVcList);
+ InitializeListHead(&pAdapter->InactiveVcList);
+
+ //
+ // Allocate memory for the hardware information.
+ //
+ ALLOCATE_MEMORY(&Status, &pAdapter->HardwareInfo, sizeof(HARDWARE_INFO));
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to allocate memory for the hardware information\n"));
+
+ break;
+ }
+
+ ZERO_MEMORY(pAdapter->HardwareInfo, sizeof(HARDWARE_INFO));
+
+ pHwInfo = pAdapter->HardwareInfo;
+
+ NdisAllocateSpinLock(&pHwInfo->Lock);
+
+ //
+ // Get the registry parameters.
+ //
+ ASSERT(pRegistryParameter[Aic5900BusNumber].fPresent);
+ pHwInfo->BusNumber = pRegistryParameter[Aic5900BusNumber].Value;
+
+ ASSERT(pRegistryParameter[Aic5900SlotNumber].fPresent);
+ pHwInfo->SlotNumber = pRegistryParameter[Aic5900SlotNumber].Value;
+
+ //
+ // Set the atributes for the adapter.
+ //
+ NdisMSetAttributes(
+ MiniportAdapterHandle,
+ (NDIS_HANDLE)pAdapter,
+ TRUE,
+ NdisInterfacePci);
+
+ //
+ // Assign the PCI resources.
+ //
+ Status = aic5900ReadPciConfiguration(pAdapter);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to read the PCI configuration information\n"));
+ break;
+ }
+
+ //
+ // Register the Port addresses.
+ //
+ Status = NdisMRegisterIoPortRange(
+ &pHwInfo->PortOffset,
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->InitialPort,
+ pHwInfo->NumberOfPorts);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to register the I/O port range\n"));
+ break;
+ }
+
+ //
+ // Get the EEPROM parameters
+ //
+ Status = aic5900ReadEepromInformation(pAdapter);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to read the EEPROM information from the adapter\n"));
+ break;
+ }
+
+ //
+ // Register the interrupt.
+ //
+ Status = NdisMRegisterInterrupt(
+ &pHwInfo->Interrupt,
+ pAdapter->MiniportAdapterHandle,
+ pHwInfo->InterruptVector,
+ pHwInfo->InterruptLevel,
+ TRUE,
+ TRUE,
+ NdisInterruptLevelSensitive);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to register the interrupt with ndis\n"));
+ break;
+ }
+
+ //
+ // Initialize the PCI device/configuration registers.
+ //
+ Status = aic5900InitPciRegisters(pAdapter);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to initialize the PCI Device/Configuration registers\n"));
+
+ break;
+ }
+
+ Status = aic5900InitPhyRegisters(pAdapter);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to initialize the PHY registers\n"));
+
+ break;
+ }
+
+ //
+ // Initialize the SAR
+ //
+ Status = aic5900InitSarRegisters(pAdapter);
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("Failed to initialize the SAR registers\n"));
+
+ break;
+ }
+
+ //
+ // Return success.
+ //
+ Status = NDIS_STATUS_SUCCESS;
+
+ } while (FALSE);
+
+ //
+ // Should we clean up?
+ //
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ aic5900FreeResources(pAdapter);
+ }
+
+ return(Status);
+}
+