Windows NT 4.0 source code leak
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

/*++
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;
}