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.
357 lines
8.8 KiB
357 lines
8.8 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
init.c
|
|
|
|
Abstract:
|
|
|
|
initialization code for pciport.sys
|
|
|
|
Author:
|
|
|
|
Ken Reneris (kenr) March-13-1885
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "pciport.h"
|
|
#include "stdio.h"
|
|
#include "stdarg.h"
|
|
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(INIT,DriverEntry)
|
|
#pragma alloc_text(PAGE,PciPortInitialize)
|
|
#endif
|
|
|
|
#if DBG
|
|
VOID
|
|
PcipTestIds (
|
|
PBUS_HANDLER PciBus
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PCI_SLOT_NUMBER SlotNumber;
|
|
ULONG Device, Function;
|
|
PPCIBUSDATA PciBusData;
|
|
PPCI_COMMON_CONFIG PciData;
|
|
UCHAR buffer[PCI_COMMON_HDR_LENGTH];
|
|
PDEVICE_DATA DeviceData;
|
|
PDEVICE_HANDLER_OBJECT DeviceHandler;
|
|
ULONG BufferSize;
|
|
PWCHAR Wptr;
|
|
WCHAR Wchar;
|
|
WCHAR DeviceId[64];
|
|
PPCI_PORT PciPort;
|
|
|
|
PAGED_CODE();
|
|
|
|
PciPort = PciBus->DeviceObject->DeviceExtension;
|
|
PciBusData = (PPCIBUSDATA) (PciBus->BusData);
|
|
PciData = (PPCI_COMMON_CONFIG) buffer;
|
|
|
|
SlotNumber.u.AsULONG = 0;
|
|
for (Device=0; Device < PCI_MAX_DEVICES; Device++) {
|
|
SlotNumber.u.bits.DeviceNumber = Device;
|
|
for (Function=0; Function < PCI_MAX_FUNCTION; Function++) {
|
|
SlotNumber.u.bits.FunctionNumber = Function;
|
|
|
|
//
|
|
// Read in the device id
|
|
//
|
|
|
|
PciBusData->ReadConfig (
|
|
PciBus,
|
|
SlotNumber,
|
|
PciData,
|
|
0,
|
|
PCI_COMMON_HDR_LENGTH
|
|
);
|
|
|
|
//
|
|
// If not valid, skip it
|
|
//
|
|
|
|
if (PciData->VendorID == PCI_INVALID_VENDORID ||
|
|
PciData->VendorID == 0 ||
|
|
(PCI_CONFIG_TYPE(PciData) != PCI_DEVICE_TYPE &&
|
|
PCI_CONFIG_TYPE(PciData) != PCI_BRIDGE_TYPE)) {
|
|
break;
|
|
}
|
|
|
|
DeviceData = PcipFindDeviceData (PciPort, SlotNumber);
|
|
ASSERT(DeviceData);
|
|
DeviceHandler = DeviceData2DeviceHandler(DeviceData);
|
|
|
|
BufferSize = sizeof (DeviceId);
|
|
Status = HalDeviceControl (
|
|
DeviceHandler,
|
|
NULL,
|
|
BCTL_QUERY_DEVICE_UNIQUE_ID,
|
|
DeviceId,
|
|
&BufferSize,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
DebugPrint ((2, "PCI: Device Unique ID: "));
|
|
for (Wptr = DeviceId; Wchar = *Wptr++; ) {
|
|
char buf[2];
|
|
buf[0] = (char) Wchar;
|
|
buf[1] = 0;
|
|
DebugPrint ((2, buf));
|
|
}
|
|
DebugPrint ((2, "\n"));
|
|
}
|
|
}
|
|
}
|
|
#endif // DBG
|
|
|
|
|
|
NTSTATUS
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Finds any currently installed PCI buses and initializes them as
|
|
pci miniport drivers
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_OBJECT DeviceObject;
|
|
PBUS_HANDLER PciBus;
|
|
NTSTATUS Status;
|
|
UNICODE_STRING unicodeString;
|
|
ULONG BusNo, junk;
|
|
BOOLEAN Install;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
PCALLBACK_OBJECT CallbackObject;
|
|
|
|
|
|
PciDriverObject = DriverObject;
|
|
|
|
//
|
|
// Add IRP handler for IRPs we care about
|
|
//
|
|
|
|
// DriverObject->MajorFunction[IRP_MJ_CREATE] =
|
|
// DriverObject->MajorFunction[IRP_MJ_CLOSE] =
|
|
// DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
|
|
// DriverObject->MajorFunction[IRP_MJ_SET_POWER] =
|
|
|
|
//
|
|
// Initialize globals
|
|
//
|
|
|
|
ExInitializeWorkItem (&PcipWorkItem, PcipControlWorker, NULL);
|
|
KeInitializeSpinLock (&PcipSpinlock);
|
|
InitializeListHead (&PcipControlWorkerList);
|
|
InitializeListHead (&PcipControlDpcList);
|
|
InitializeListHead (&PcipCheckBusList);
|
|
ExInitializeFastMutex (&PcipMutex);
|
|
ASSERT(PcipMutex.Owner == NULL);
|
|
PcipDeviceHandlerObjectSize = *IoDeviceHandlerObjectSize;
|
|
|
|
//
|
|
// Register on system suspend/hibernate callback
|
|
//
|
|
|
|
RtlInitUnicodeString(&unicodeString, rgzSuspendCallbackName);
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&unicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
Status = ExCreateCallback (&CallbackObject, &ObjectAttributes, FALSE, FALSE);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
PciSuspendRegistration = ExRegisterCallback (
|
|
CallbackObject,
|
|
PcipSuspendNotification,
|
|
NULL
|
|
);
|
|
|
|
ObDereferenceObject (CallbackObject);
|
|
|
|
//
|
|
// Get access to the HAL callback objects
|
|
//
|
|
|
|
HalQuerySystemInformation (
|
|
HalCallbackInformation,
|
|
sizeof (PciHalCallbacks),
|
|
&PciHalCallbacks,
|
|
&junk
|
|
);
|
|
|
|
//
|
|
// For each installed PCI bus
|
|
//
|
|
|
|
_asm int 3;
|
|
|
|
Install = FALSE;
|
|
for (BusNo=0; TRUE; BusNo += 1) {
|
|
PciBus = HalHandlerForBus (PCIBus, BusNo);
|
|
|
|
if (!PciBus) {
|
|
break;
|
|
}
|
|
|
|
Status = PciPortInitialize (PciBus);
|
|
if (NT_SUCCESS(Status)) {
|
|
Install = TRUE;
|
|
}
|
|
}
|
|
|
|
if (Install) {
|
|
DebugPrint ((1, "PCI: Installed\n"));
|
|
#if DBG
|
|
for (BusNo=0; PciBus = HalHandlerForBus (PCIBus, BusNo); BusNo += 1) {
|
|
PcipTestIds(PciBus);
|
|
}
|
|
#endif
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Not installing - uninitialize
|
|
//
|
|
|
|
DebugPrint ((1, "PCI: No internal PCI buses found - not installing\n"));
|
|
ExUnregisterCallback (PciSuspendRegistration);
|
|
|
|
return STATUS_NO_SUCH_DEVICE;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
PciPortInitialize (
|
|
PBUS_HANDLER PciBus
|
|
)
|
|
{
|
|
PPCIBUSDATA PciBusData;
|
|
PDEVICE_OBJECT BusDeviceObject;
|
|
WCHAR buffer[100];
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
NTSTATUS Status;
|
|
UNICODE_STRING unicodeString;
|
|
PPCI_PORT PciPort;
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// Verify bus handler is a PCI miniport driver
|
|
//
|
|
|
|
PciBusData = (PPCIBUSDATA) PciBus->BusData;
|
|
if (PciBus->InterfaceType != PCIBus ||
|
|
PciBus->ConfigurationType != PCIConfiguration ||
|
|
!PciBusData ||
|
|
PciBusData->Tag != PCI_DATA_TAG ||
|
|
PciBusData->Version != PCI_DATA_VERSION) {
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Create device object for this bus extention
|
|
//
|
|
|
|
swprintf (buffer, rgzPCIDeviceName, PciBus->BusNumber);
|
|
RtlInitUnicodeString (&unicodeString, buffer);
|
|
|
|
Status = IoCreateDevice(
|
|
PciDriverObject,
|
|
sizeof (PCI_PORT),
|
|
&unicodeString,
|
|
FILE_DEVICE_BUS_EXTENDER,
|
|
0,
|
|
FALSE,
|
|
&BusDeviceObject
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
DebugPrint ((1, "PCI: Adding PCI bus %d\n", PciBus->BusNumber));
|
|
|
|
//
|
|
// Install pointer to pci extension structure
|
|
//
|
|
|
|
PciBusData->Version = 0;
|
|
PciBusData->PciExtension = (PVOID) BusDeviceObject->DeviceExtension;
|
|
PciBus->DeviceObject = BusDeviceObject;
|
|
|
|
//
|
|
// Initialize internal pci port structure
|
|
//
|
|
|
|
PciPort = (PPCI_PORT) BusDeviceObject->DeviceExtension;
|
|
RtlZeroMemory (PciPort, sizeof (PCI_PORT));
|
|
PciPort->Handler = PciBus;
|
|
InitializeListHead (&PciPort->CheckBus);
|
|
InitializeListHead (&PciPort->DeviceControl);
|
|
|
|
//
|
|
// Intall bus specific handlers
|
|
//
|
|
|
|
PciBus->GetBusData = (PGETSETBUSDATA) PcipGetBusData;
|
|
PciBus->SetBusData = (PGETSETBUSDATA) PcipSetBusData;
|
|
PciBus->AssignSlotResources = (PASSIGNSLOTRESOURCES) PcipAssignSlotResources;
|
|
PciBus->QueryBusSlots = (PQUERY_BUS_SLOTS) PcipQueryBusSlots;
|
|
PciBus->DeviceControl = (PDEVICE_CONTROL) PcipDeviceControl;
|
|
PciBus->ReferenceDeviceHandler = (PREFERENCE_DEVICE_HANDLER) PcipReferenceDeviceHandler;
|
|
PciBus->GetDeviceData = (PGET_SET_DEVICE_DATA) PcipGetDeviceData;
|
|
PciBus->SetDeviceData = (PGET_SET_DEVICE_DATA) PcipSetDeviceData;
|
|
PciBus->HibernateBus = (PHIBERNATEBRESUMEBUS) PcipHibernateBus;
|
|
PciBus->ResumeBus = (PHIBERNATEBRESUMEBUS) PcipResumeBus;
|
|
|
|
//
|
|
// We don't need power control irps - we'll handle all system power
|
|
// requests via the SystemSuspendHiberante callback and the
|
|
// bus extender Hibernate & Resume bus entry points
|
|
//
|
|
|
|
BusDeviceObject->DeviceObjectExtension->PowerControlNeeded = FALSE;
|
|
|
|
//
|
|
// BUGBUG: we need to report the resources this PCI bus is using
|
|
//
|
|
|
|
//
|
|
// Perform initial bus check
|
|
//
|
|
|
|
PcipCheckBus (PciPort, TRUE);
|
|
return STATUS_SUCCESS;
|
|
}
|