mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1040 lines
18 KiB
1040 lines
18 KiB
/*++
|
|
|
|
Module Name:
|
|
|
|
detpci.c
|
|
|
|
Abstract:
|
|
|
|
This is the main file for the autodetection DLL for the PCI DC21X4 adapter
|
|
for Windows NT.
|
|
|
|
|
|
--*/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <pci.h>
|
|
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "ntddnetd.h"
|
|
#include "detect.h"
|
|
|
|
//
|
|
// Individual card detection routines
|
|
//
|
|
|
|
//
|
|
// Helper functions
|
|
//
|
|
|
|
ULONG
|
|
FindPciCard(
|
|
IN ULONG AdapterNumber,
|
|
IN ULONG BusNumber,
|
|
IN BOOLEAN First,
|
|
OUT PULONG Confidence
|
|
);
|
|
|
|
//
|
|
// Structure for holding a particular adapter's complete information
|
|
//
|
|
typedef struct _PCI_ADAPTER_INFO
|
|
{
|
|
LONG Index;
|
|
PWCHAR InfId;
|
|
ULONG CfId;
|
|
ULONG CfgMask;
|
|
PWCHAR Parameters;
|
|
NC_DETECT_FIRST_NEXT FirstNext;
|
|
|
|
ULONG BusNumber;
|
|
ULONG SlotNumber;
|
|
}
|
|
PCI_ADAPTER_INFO,
|
|
*PPCI_ADAPTER_INFO;
|
|
|
|
UINT gLoadPciAdapterInfo = 0;
|
|
ULONG gNumberOfPciAdapters = 0;
|
|
PPCI_ADAPTER_INFO gPciAdapterList = NULL;
|
|
PWCHAR gPciParameters = L"SLOTNUMBER\0"
|
|
L"1\0"
|
|
L"100\0";
|
|
|
|
#define PCI_SEARCH_ORDER 999
|
|
|
|
VOID
|
|
FreePciAdapterInfo(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
if (--gLoadPciAdapterInfo == 0)
|
|
{
|
|
FreeAdapterInformation(gPciAdapterList, gNumberOfPciAdapters);
|
|
gPciAdapterList = NULL;
|
|
gNumberOfPciAdapters = 0;
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
LoadPciAdapterInfo(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
PPCI_ADAPTER_INFO AdapterList;
|
|
UINT NumberOfAdapters;
|
|
BOOLEAN f;
|
|
UINT c;
|
|
|
|
//
|
|
// Have we already loaded the adapter information?
|
|
//
|
|
if (gLoadPciAdapterInfo > 0)
|
|
{
|
|
gLoadPciAdapterInfo++;
|
|
return(TRUE);
|
|
}
|
|
|
|
//
|
|
// Load the registry specific information.
|
|
//
|
|
f = LoadAdapterInformation(
|
|
L"PCI",
|
|
sizeof(PCI_ADAPTER_INFO),
|
|
&AdapterList,
|
|
&NumberOfAdapters);
|
|
if (!f || (0 == NumberOfAdapters))
|
|
{
|
|
#if _DBG
|
|
DbgPrint("LoadAdapterInformation(PCI) failed!\n");
|
|
#endif
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Fill in common adapter information
|
|
//
|
|
for (c = 0; c < NumberOfAdapters; c++)
|
|
{
|
|
AdapterList[c].Parameters = gPciParameters;
|
|
}
|
|
|
|
gNumberOfPciAdapters = NumberOfAdapters;
|
|
gPciAdapterList = AdapterList;
|
|
gLoadPciAdapterInfo = 1;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
PciIdentifyHandler(
|
|
IN LONG Index,
|
|
IN WCHAR * Buffer,
|
|
IN LONG BuffSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns information about the netcards supported by
|
|
this file.
|
|
|
|
Arguments:
|
|
|
|
Index - The index of the netcard being address. The first
|
|
cards information is at index 1000, the second at 1100, etc.
|
|
|
|
Buffer - Buffer to store the result into.
|
|
|
|
BuffSize - Number of bytes in Buffer
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
LONG Code = Index % 100;
|
|
LONG Length;
|
|
ULONG i;
|
|
|
|
#if _DBG
|
|
DbgPrint("==>PciIdentifyHandler\n");
|
|
#endif
|
|
|
|
Index = Index - Code;
|
|
|
|
if ((ULONG)((Index / 100) - 10) < gNumberOfPciAdapters)
|
|
{
|
|
//
|
|
// Find the correct adapter ID
|
|
//
|
|
for (i = 0; i < gNumberOfPciAdapters; i++)
|
|
{
|
|
if (gPciAdapterList[i].Index == Index)
|
|
{
|
|
switch (Code)
|
|
{
|
|
case 0:
|
|
//
|
|
// Find the string length
|
|
//
|
|
Length = UnicodeStrLen(gPciAdapterList[i].InfId);
|
|
|
|
Length ++;
|
|
|
|
if (BuffSize < Length)
|
|
{
|
|
#if _DBG
|
|
DbgPrint("<==PciIdentifyHandler: 0x%x\n", ERROR_INSUFFICIENT_BUFFER);
|
|
#endif
|
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|
}
|
|
|
|
memcpy((PVOID)Buffer, gPciAdapterList[i].InfId, Length * sizeof(WCHAR));
|
|
break;
|
|
|
|
case 3:
|
|
|
|
//
|
|
// Maximum value is 1000
|
|
//
|
|
if (BuffSize < 5)
|
|
{
|
|
#if _DBG
|
|
DbgPrint("<==PciIdentifyHandler: 0x%x\n", ERROR_INSUFFICIENT_BUFFER);
|
|
#endif
|
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|
}
|
|
|
|
wsprintfW((PVOID)Buffer, L"%d", PCI_SEARCH_ORDER);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
#if _DBG
|
|
DbgPrint("<==PciIdentifyHandler: 0x%x\n", ERROR_INVALID_PARAMETER);
|
|
#endif
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
#if _DBG
|
|
DbgPrint("<==PciIdentifyHandler: 0x%x\n", 0);
|
|
#endif
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
#if _DBG
|
|
DbgPrint("<==PciIdentifyHandler: 0x%x\n", ERROR_INVALID_PARAMETER);
|
|
#endif
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
#if _DBG
|
|
DbgPrint("<==PciIdentifyHandler: 0x%x\n", ERROR_NO_MORE_ITEMS);
|
|
#endif
|
|
|
|
return(ERROR_NO_MORE_ITEMS);
|
|
}
|
|
|
|
|
|
extern
|
|
LONG
|
|
PciFirstNextHandler(
|
|
IN LONG NetcardId,
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN ULONG BusNumber,
|
|
IN BOOL First,
|
|
OUT PVOID *Token,
|
|
OUT LONG *Confidence
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine finds the instances of a physical adapter identified
|
|
by the NetcardId.
|
|
|
|
Arguments:
|
|
|
|
NetcardId - The index of the netcard being address. The first
|
|
cards information is id 1000, the second id 1100, etc.
|
|
|
|
InterfaceType - Microchannel
|
|
|
|
BusNumber - The bus number of the bus to search.
|
|
|
|
First - TRUE is we are to search for the first instance of an
|
|
adapter, FALSE if we are to continue search from a previous stopping
|
|
point.
|
|
|
|
Token - A pointer to a handle to return to identify the found
|
|
instance
|
|
|
|
Confidence - A pointer to a long for storing the confidence factor
|
|
that the card exists.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG Cfid;
|
|
ULONG ReturnValue;
|
|
ULONG NetCardIndex;
|
|
|
|
#if _DBG
|
|
DbgPrint("==>PciFirstNextHandler\n");
|
|
#endif
|
|
|
|
if (InterfaceType != PCIBus)
|
|
{
|
|
#if _DBG
|
|
DbgPrint("<==PciFirstNextHandler: 0x%x:0x%x\n", 0, 0);
|
|
#endif
|
|
|
|
*Confidence = 0;
|
|
return(0);
|
|
}
|
|
|
|
//
|
|
// Index of the netcard in our array of adapters that we are looking for.
|
|
//
|
|
NetCardIndex = (NetcardId / 100) - 10;
|
|
|
|
//
|
|
// Call FindFirst Routine
|
|
//
|
|
|
|
ReturnValue = FindPciCard(
|
|
NetCardIndex,
|
|
BusNumber,
|
|
(BOOLEAN)First,
|
|
Confidence);
|
|
if (ReturnValue == 0)
|
|
{
|
|
#if _DBG
|
|
DbgPrint("FindFirstNext, FindPciCard OK!\n");
|
|
#endif
|
|
*Token = (PVOID)NetCardIndex;
|
|
}
|
|
|
|
#if _DBG
|
|
DbgPrint("<==PciFirstNextHandler: 0x%x:0x%x\n", ReturnValue, Confidence);
|
|
#endif
|
|
|
|
return(ReturnValue);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
PciOpenHandleHandler(
|
|
IN PVOID Token,
|
|
OUT PVOID *Handle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine takes a token returned by FirstNext and converts it
|
|
into a permanent handle.
|
|
|
|
Arguments:
|
|
|
|
Token - The token.
|
|
|
|
Handle - A pointer to the handle, so we can store the resulting
|
|
handle.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
#if _DBG
|
|
DbgPrint("==>PciOpenHandleHandler\n");
|
|
#endif
|
|
|
|
//
|
|
// The token is the index into the adapter list for the adapter
|
|
// that they want to open.
|
|
//
|
|
*Handle = (PVOID)&gPciAdapterList[(ULONG)Token];
|
|
|
|
#if _DBG
|
|
DbgPrint("<==PciOpenHandleHandler: 0x%x\n", 0);
|
|
#endif
|
|
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
PciCreateHandleHandler(
|
|
IN LONG NetcardId,
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN ULONG BusNumber,
|
|
OUT PVOID *Handle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to force the creation of a handle for cases
|
|
where a card is not found via FirstNext, but the user says it does
|
|
exist.
|
|
|
|
Arguments:
|
|
|
|
NetcardId - The id of the card to create the handle for.
|
|
|
|
InterfaceType - Microchannel
|
|
|
|
BusNumber - The bus number of the bus in the system.
|
|
|
|
Handle - A pointer to the handle, for storing the resulting handle.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG i;
|
|
|
|
#if _DBG
|
|
DbgPrint("==>PciCreateHandleHandler\n");
|
|
#endif
|
|
|
|
if (InterfaceType != PCIBus)
|
|
{
|
|
#if _DBG
|
|
DbgPrint("<==PciCreateHandleHandler: 0x%x\n", ERROR_INVALID_PARAMETER);
|
|
#endif
|
|
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
for (i = 0; i < gNumberOfPciAdapters; i++)
|
|
{
|
|
if (gPciAdapterList[i].Index == NetcardId)
|
|
{
|
|
gPciAdapterList[i].SlotNumber = 1;
|
|
gPciAdapterList[i].BusNumber = BusNumber;
|
|
|
|
*Handle = (PVOID)&gPciAdapterList[i];
|
|
|
|
#if _DBG
|
|
DbgPrint("<==PciCreateHandleHandler: 0x%x\n", 0);
|
|
#endif
|
|
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
#if _DBG
|
|
DbgPrint("<==PciCreateHandleHandler: 0x%x\n", ERROR_INVALID_PARAMETER);
|
|
#endif
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
PciCloseHandleHandler(
|
|
IN PVOID Handle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This frees any resources associated with a handle.
|
|
|
|
Arguments:
|
|
|
|
Handle - The handle.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
#if _DBG
|
|
DbgPrint("<==>PciCloseHandleHandler: 0x%x\n", 0);
|
|
#endif
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
PciQueryCfgHandler(
|
|
IN PVOID Handle,
|
|
OUT WCHAR *Buffer,
|
|
IN LONG BuffSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine calls the appropriate driver's query config handler to
|
|
get the parameters for the adapter associated with the handle.
|
|
|
|
Arguments:
|
|
|
|
Handle - The handle.
|
|
|
|
Buffer - The resulting parameter list.
|
|
|
|
BuffSize - Length of the given buffer in WCHARs.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
PPCI_ADAPTER_INFO pAdapter = (PPCI_ADAPTER_INFO)Handle;
|
|
PPCI_COMMON_CONFIG PciData;
|
|
ULONG PciBuffer;
|
|
PPCI_ADAPTER_INFO Adapter = (PPCI_ADAPTER_INFO)(Handle);
|
|
LONG CopyLength;
|
|
ULONG CfId;
|
|
ULONG ReturnValue;
|
|
ULONG Confidence;
|
|
LONG OutputLength = 0;
|
|
NTSTATUS Status;
|
|
|
|
#if _DBG
|
|
DbgPrint("QueryCfgHandler; Bus: %d, Slot: %d Adpt Cardtype: %d\n",
|
|
Adapter->BusNumber,
|
|
Adapter->SlotNumber,
|
|
Adapter->Index);
|
|
#endif
|
|
|
|
//
|
|
// Verify the SlotNumber
|
|
//
|
|
PciData = (PPCI_COMMON_CONFIG)&PciBuffer;
|
|
|
|
Status = DetectReadPciSlotInformation(
|
|
Adapter->BusNumber,
|
|
Adapter->SlotNumber,
|
|
0x0,
|
|
sizeof(PciBuffer),
|
|
PciData);
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
#if _DBG
|
|
DbgPrint("DetectReadPciSlotInformation STATUS_SUCCESS\n");
|
|
DbgPrint("Cfid: %08x, VendorId: %4x\n", PciBuffer, PciData->VendorID );
|
|
#endif
|
|
|
|
ReturnValue = ERROR_INVALID_PARAMETER;
|
|
|
|
if (pAdapter->CfId == PciBuffer)
|
|
{
|
|
ReturnValue = 0;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Try to find it in another slot
|
|
//
|
|
ReturnValue = FindPciCard(
|
|
pAdapter->Index,
|
|
pAdapter->BusNumber,
|
|
TRUE,
|
|
&Confidence);
|
|
if (Confidence != 100)
|
|
{
|
|
//
|
|
// Confidence is not absolute -- we are out of here.
|
|
//
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Build resulting buffer
|
|
//
|
|
|
|
//
|
|
// Put in SlotNumber
|
|
//
|
|
|
|
//
|
|
// Copy in the title string
|
|
//
|
|
|
|
#if _DBG
|
|
DbgPrint("Build Resulting Buffer\n");
|
|
#endif
|
|
|
|
CopyLength = UnicodeStrLen(SlotNumberString) + 1;
|
|
|
|
if ((BuffSize-OutputLength) < CopyLength)
|
|
{
|
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|
}
|
|
|
|
memcpy((PVOID)Buffer, (PVOID)SlotNumberString, (CopyLength * sizeof(WCHAR)));
|
|
|
|
OutputLength += CopyLength;
|
|
|
|
//
|
|
// Copy in the value
|
|
//
|
|
if ((BuffSize - OutputLength) < 8)
|
|
{
|
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|
}
|
|
|
|
CopyLength = wsprintfW(&Buffer[OutputLength],L"0x%x",(ULONG)(pAdapter->SlotNumber));
|
|
|
|
if (CopyLength < 0)
|
|
{
|
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|
}
|
|
|
|
CopyLength++;
|
|
OutputLength += CopyLength;
|
|
|
|
//
|
|
// Copy in final \0
|
|
//
|
|
if ((BuffSize - OutputLength) < 1)
|
|
{
|
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|
}
|
|
|
|
Buffer[OutputLength++] = L'\0';
|
|
Buffer = &(Buffer[OutputLength]);
|
|
|
|
return(0);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
PciVerifyCfgHandler(
|
|
IN PVOID Handle,
|
|
IN WCHAR *Buffer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine verifys that a given parameter list is complete and
|
|
correct for the adapter associated with the handle.
|
|
|
|
Arguments:
|
|
|
|
Handle - The handle.
|
|
|
|
Buffer - The parameter list.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
PPCI_COMMON_CONFIG PciData;
|
|
ULONG PciBuffer;
|
|
PPCI_ADAPTER_INFO pAdapter = (PPCI_ADAPTER_INFO)Handle;
|
|
WCHAR *Place;
|
|
ULONG SlotNumber;
|
|
BOOLEAN Found;
|
|
NTSTATUS Status;
|
|
|
|
#if _DBG
|
|
DbgPrint("PciVerifyCfgHandler\n");
|
|
#endif
|
|
|
|
//
|
|
// Parse out the parameter.
|
|
//
|
|
|
|
//
|
|
// Get the SlotNumber
|
|
//
|
|
|
|
Place = FindParameterString(Buffer, SlotNumberString);
|
|
if (Place == NULL)
|
|
{
|
|
return(ERROR_INVALID_DATA);
|
|
}
|
|
|
|
Place += UnicodeStrLen(SlotNumberString) + 1;
|
|
|
|
//
|
|
// Now parse the thing.
|
|
//
|
|
ScanForNumber(Place, &SlotNumber, &Found);
|
|
|
|
if (Found == FALSE)
|
|
{
|
|
return(ERROR_INVALID_DATA);
|
|
}
|
|
|
|
//
|
|
// Verify the SlotNumber
|
|
//
|
|
PciData = (PPCI_COMMON_CONFIG)&PciBuffer;
|
|
|
|
#if _DBG
|
|
DbgPrint("BusNumber: %d, Slot: %d\n", pAdapter->BusNumber, SlotNumber);
|
|
#endif
|
|
|
|
Status = DetectReadPciSlotInformation(
|
|
pAdapter->BusNumber,
|
|
SlotNumber,
|
|
0x0,
|
|
sizeof(PciBuffer),
|
|
PciData);
|
|
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
return(ERROR_INVALID_DATA);
|
|
}
|
|
|
|
#if _DBG
|
|
DbgPrint("Cfid: %08x, VendorId: %4x\n", PciBuffer, PciData->VendorID);
|
|
#endif
|
|
|
|
if (PciData->VendorID == PCI_INVALID_VENDORID)
|
|
{
|
|
//
|
|
// No PCI device, or no functions on device
|
|
//
|
|
return(ERROR_INVALID_DATA);
|
|
}
|
|
|
|
if (pAdapter->CfId != PciBuffer)
|
|
{
|
|
return(ERROR_INVALID_DATA);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
PciQueryMaskHandler(
|
|
IN LONG NetcardId,
|
|
OUT WCHAR *Buffer,
|
|
IN LONG BuffSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns the parameter list information for a specific
|
|
network card.
|
|
|
|
Arguments:
|
|
|
|
NetcardId - The id of the desired netcard.
|
|
|
|
Buffer - The buffer for storing the parameter information.
|
|
|
|
BuffSize - Length of Buffer in WCHARs.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
WCHAR *Result;
|
|
LONG Length;
|
|
ULONG i;
|
|
|
|
//
|
|
// Find the adapter
|
|
//
|
|
for (i = 0; i < gNumberOfPciAdapters; i++)
|
|
{
|
|
if (gPciAdapterList[i].Index == NetcardId)
|
|
{
|
|
Result = gPciAdapterList[i].Parameters;
|
|
|
|
//
|
|
// Find the string length (Ends with 2 NULLs)
|
|
//
|
|
for (Length=0; ; Length++)
|
|
{
|
|
if (Result[Length] == L'\0')
|
|
{
|
|
++Length;
|
|
|
|
if (Result[Length] == L'\0')
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Length++;
|
|
|
|
if (BuffSize < Length)
|
|
{
|
|
return(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
|
|
memcpy((PVOID)Buffer, Result, Length * sizeof(WCHAR));
|
|
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
PciParamRangeHandler(
|
|
IN LONG NetcardId,
|
|
IN WCHAR *Param,
|
|
OUT LONG *Values,
|
|
OUT LONG *BuffSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns a list of valid values for a given parameter name
|
|
for a given card.
|
|
|
|
Arguments:
|
|
|
|
NetcardId - The Id of the card desired.
|
|
|
|
Param - A WCHAR string of the parameter name to query the values of.
|
|
|
|
Values - A pointer to a list of LONGs into which we store valid values
|
|
for the parameter.
|
|
|
|
BuffSize - At entry, the length of Values in LONGs. At exit, the
|
|
number of LONGs stored in Values.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
*BuffSize = 0;
|
|
return(0);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
PciQueryParameterNameHandler(
|
|
IN WCHAR *Param,
|
|
OUT WCHAR *Buffer,
|
|
IN LONG BufferSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns a localized, displayable name for a specific parameter. All the
|
|
parameters that this file uses are define by MS, so no strings are
|
|
needed here.
|
|
|
|
Arguments:
|
|
|
|
Param - The parameter to be queried.
|
|
|
|
Buffer - The buffer to store the result into.
|
|
|
|
BufferSize - The length of Buffer in WCHARs.
|
|
|
|
Return Value:
|
|
|
|
ERROR_INVALID_PARAMETER -- To indicate that the MS supplied strings
|
|
should be used.
|
|
|
|
--*/
|
|
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
|
|
|
|
/*+
|
|
*
|
|
FindPciCard
|
|
*
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* Walk the PCI slots looking for Vendor and Product ID matches.
|
|
*
|
|
*
|
|
* Arguments:
|
|
*
|
|
* AdapterNumber - The index into the global array of adapters for the card.
|
|
*
|
|
* BusNumber - The bus number of the bus to search.
|
|
*
|
|
* First - TRUE is we are to search for the first instance of an
|
|
* adapter, FALSE if we are to continue search from a previous stopping
|
|
* point.
|
|
*
|
|
* CfId - The PCI Configuration Id of the card.
|
|
*
|
|
* Confidence - A pointer to a long for storing the confidence factor
|
|
* that the card exists.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* 0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
*
|
|
-*/
|
|
|
|
|
|
ULONG
|
|
FindPciCard(
|
|
IN ULONG AdapterNumber,
|
|
IN ULONG BusNumber,
|
|
IN BOOLEAN First,
|
|
OUT PULONG Confidence
|
|
)
|
|
{
|
|
PPCI_ADAPTER_INFO pAdapter = &gPciAdapterList[AdapterNumber];
|
|
PPCI_COMMON_CONFIG PciData;
|
|
ULONG PciBuffer;
|
|
PCI_SLOT_NUMBER Slot;
|
|
NTSTATUS Status;
|
|
|
|
#if _DBG
|
|
DbgPrint("FindPciAdapter: %08x, FIRST: %d\n", pAdapter->CfId, First);
|
|
#endif
|
|
|
|
PciData = (PPCI_COMMON_CONFIG)&PciBuffer;
|
|
|
|
if (First)
|
|
{
|
|
pAdapter->SlotNumber = 0;
|
|
}
|
|
else
|
|
{
|
|
pAdapter->SlotNumber++;
|
|
#if _DBG
|
|
DbgPrint("Adapter Number: %d, Slot Number: %d\n", AdapterNumber, pAdapter->SlotNumber);
|
|
#endif
|
|
}
|
|
|
|
if (pAdapter->SlotNumber >= PCI_MAX_DEVICES)
|
|
{
|
|
return (ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
//
|
|
// Look at each device starting at the last
|
|
// device (slot) previously found.
|
|
//
|
|
while (pAdapter->SlotNumber < PCI_MAX_DEVICES)
|
|
{
|
|
Slot.u.AsULONG = 0;
|
|
Slot.u.bits.DeviceNumber = pAdapter->SlotNumber;
|
|
Slot.u.bits.FunctionNumber = 0;
|
|
|
|
#if _DBG
|
|
DbgPrint("Bus=%d Dev=%d Fct=%d : \n",
|
|
BusNumber,
|
|
Slot.u.bits.DeviceNumber,
|
|
Slot.u.bits.FunctionNumber);
|
|
#endif
|
|
|
|
Status = DetectReadPciSlotInformation(
|
|
BusNumber,
|
|
Slot.u.AsULONG,
|
|
0x0,
|
|
sizeof(PciBuffer),
|
|
PciData);
|
|
|
|
//
|
|
// Out of PCI data.
|
|
//
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
*Confidence = 0;
|
|
return(1);
|
|
}
|
|
|
|
#if _DBG
|
|
DbgPrint(" CFID=%8x VendorID = %4x\n", PciBuffer, PciData->VendorID);
|
|
#endif
|
|
|
|
//
|
|
// Compare id's
|
|
//
|
|
if (PciBuffer == pAdapter->CfId)
|
|
{
|
|
#if _DBG
|
|
DbgPrint(" %x found in Slot %04x\n", pAdapter->CfId, Slot.u.AsULONG);
|
|
#endif
|
|
*Confidence = 100;
|
|
return (0);
|
|
}
|
|
|
|
pAdapter->SlotNumber++;
|
|
}
|
|
|
|
*Confidence = 0;
|
|
return(1);
|
|
}
|
|
|
|
|