mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 06:53:00 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
12
drivers/bus/pci/CMakeLists.txt
Normal file
12
drivers/bus/pci/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
fdo.c
|
||||
pci.c
|
||||
pdo.c
|
||||
pci.h)
|
||||
|
||||
add_library(pci SHARED ${SOURCE} pci.rc)
|
||||
set_module_type(pci kernelmodedriver)
|
||||
add_importlibs(pci ntoskrnl hal)
|
||||
add_pch(pci pci.h SOURCE)
|
||||
add_cd_file(TARGET pci DESTINATION reactos/system32/drivers NO_CAB FOR all)
|
608
drivers/bus/pci/fdo.c
Normal file
608
drivers/bus/pci/fdo.c
Normal file
|
@ -0,0 +1,608 @@
|
|||
/*
|
||||
* PROJECT: ReactOS PCI bus driver
|
||||
* FILE: fdo.c
|
||||
* PURPOSE: PCI device object dispatch routines
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* UPDATE HISTORY:
|
||||
* 10-09-2001 CSH Created
|
||||
*/
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/*** PRIVATE *****************************************************************/
|
||||
|
||||
static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion;
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
ForwardIrpAndWaitCompletion(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
if (Irp->PendingReturned)
|
||||
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ForwardIrpAndWait(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Ldo;
|
||||
ASSERT(LowerDevice);
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
|
||||
|
||||
Status = IoCallDriver(LowerDevice, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
FdoLocateChildDevice(
|
||||
PPCI_DEVICE *Device,
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension,
|
||||
PCI_SLOT_NUMBER SlotNumber,
|
||||
PPCI_COMMON_CONFIG PciConfig)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PPCI_DEVICE CurrentDevice;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
||||
while (CurrentEntry != &DeviceExtension->DeviceListHead)
|
||||
{
|
||||
CurrentDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
|
||||
|
||||
/* If both vendor ID and device ID match, it is the same device */
|
||||
if ((PciConfig->VendorID == CurrentDevice->PciConfig.VendorID) &&
|
||||
(PciConfig->DeviceID == CurrentDevice->PciConfig.DeviceID) &&
|
||||
(SlotNumber.u.AsULONG == CurrentDevice->SlotNumber.u.AsULONG))
|
||||
{
|
||||
*Device = CurrentDevice;
|
||||
DPRINT("Done\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
|
||||
*Device = NULL;
|
||||
DPRINT("Done\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
FdoEnumerateDevices(
|
||||
PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PCI_COMMON_CONFIG PciConfig;
|
||||
PPCI_DEVICE Device;
|
||||
PCI_SLOT_NUMBER SlotNumber;
|
||||
ULONG DeviceNumber;
|
||||
ULONG FunctionNumber;
|
||||
ULONG Size;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
DeviceExtension->DeviceListCount = 0;
|
||||
|
||||
/* Enumerate devices on the PCI bus */
|
||||
SlotNumber.u.AsULONG = 0;
|
||||
for (DeviceNumber = 0; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
|
||||
{
|
||||
SlotNumber.u.bits.DeviceNumber = DeviceNumber;
|
||||
for (FunctionNumber = 0; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
|
||||
{
|
||||
SlotNumber.u.bits.FunctionNumber = FunctionNumber;
|
||||
|
||||
DPRINT("Bus %1lu Device %2lu Func %1lu\n",
|
||||
DeviceExtension->BusNumber,
|
||||
DeviceNumber,
|
||||
FunctionNumber);
|
||||
|
||||
RtlZeroMemory(&PciConfig,
|
||||
sizeof(PCI_COMMON_CONFIG));
|
||||
|
||||
Size = HalGetBusData(PCIConfiguration,
|
||||
DeviceExtension->BusNumber,
|
||||
SlotNumber.u.AsULONG,
|
||||
&PciConfig,
|
||||
PCI_COMMON_HDR_LENGTH);
|
||||
DPRINT("Size %lu\n", Size);
|
||||
if (Size < PCI_COMMON_HDR_LENGTH)
|
||||
{
|
||||
if (FunctionNumber == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n",
|
||||
DeviceExtension->BusNumber,
|
||||
DeviceNumber,
|
||||
FunctionNumber,
|
||||
PciConfig.VendorID,
|
||||
PciConfig.DeviceID);
|
||||
|
||||
Status = FdoLocateChildDevice(&Device, DeviceExtension, SlotNumber, &PciConfig);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Device = ExAllocatePoolWithTag(NonPagedPool, sizeof(PCI_DEVICE), TAG_PCI);
|
||||
if (!Device)
|
||||
{
|
||||
/* FIXME: Cleanup resources for already discovered devices */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlZeroMemory(Device,
|
||||
sizeof(PCI_DEVICE));
|
||||
|
||||
Device->BusNumber = DeviceExtension->BusNumber;
|
||||
|
||||
RtlCopyMemory(&Device->SlotNumber,
|
||||
&SlotNumber,
|
||||
sizeof(PCI_SLOT_NUMBER));
|
||||
|
||||
RtlCopyMemory(&Device->PciConfig,
|
||||
&PciConfig,
|
||||
sizeof(PCI_COMMON_CONFIG));
|
||||
|
||||
ExInterlockedInsertTailList(
|
||||
&DeviceExtension->DeviceListHead,
|
||||
&Device->ListEntry,
|
||||
&DeviceExtension->DeviceListLock);
|
||||
}
|
||||
|
||||
DeviceExtension->DeviceListCount++;
|
||||
|
||||
/* Skip to next device if the current one is not a multifunction device */
|
||||
if ((FunctionNumber == 0) &&
|
||||
((PciConfig.HeaderType & 0x80) == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("Done\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
FdoQueryBusRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION PdoDeviceExtension = NULL;
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_RELATIONS Relations;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PPCI_DEVICE Device;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN ErrorOccurred;
|
||||
NTSTATUS ErrorStatus;
|
||||
ULONG Size;
|
||||
ULONG i;
|
||||
|
||||
UNREFERENCED_PARAMETER(IrpSp);
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
ErrorOccurred = FALSE;
|
||||
|
||||
FdoEnumerateDevices(DeviceObject);
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (Irp->IoStatus.Information)
|
||||
{
|
||||
/* FIXME: Another bus driver has already created a DEVICE_RELATIONS
|
||||
structure so we must merge this structure with our own */
|
||||
DPRINT1("FIXME: leaking old bus relations\n");
|
||||
}
|
||||
|
||||
Size = sizeof(DEVICE_RELATIONS) +
|
||||
sizeof(Relations->Objects) * (DeviceExtension->DeviceListCount - 1);
|
||||
Relations = ExAllocatePoolWithTag(PagedPool, Size, TAG_PCI);
|
||||
if (!Relations)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Relations->Count = DeviceExtension->DeviceListCount;
|
||||
|
||||
i = 0;
|
||||
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
||||
while (CurrentEntry != &DeviceExtension->DeviceListHead)
|
||||
{
|
||||
Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
|
||||
|
||||
PdoDeviceExtension = NULL;
|
||||
|
||||
if (!Device->Pdo)
|
||||
{
|
||||
/* Create a physical device object for the
|
||||
device as it does not already have one */
|
||||
Status = IoCreateDevice(DeviceObject->DriverObject,
|
||||
sizeof(PDO_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_CONTROLLER,
|
||||
FILE_AUTOGENERATED_DEVICE_NAME,
|
||||
FALSE,
|
||||
&Device->Pdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
||||
ErrorStatus = Status;
|
||||
ErrorOccurred = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
//Device->Pdo->Flags |= DO_POWER_PAGABLE;
|
||||
|
||||
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
|
||||
|
||||
RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
|
||||
|
||||
PdoDeviceExtension->Common.IsFDO = FALSE;
|
||||
|
||||
PdoDeviceExtension->Common.DeviceObject = Device->Pdo;
|
||||
|
||||
PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;
|
||||
|
||||
PdoDeviceExtension->Fdo = DeviceObject;
|
||||
|
||||
PdoDeviceExtension->PciDevice = Device;
|
||||
|
||||
/* Add Device ID string */
|
||||
Status = PciCreateDeviceIDString(&PdoDeviceExtension->DeviceID, Device);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorStatus = Status;
|
||||
ErrorOccurred = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT("DeviceID: %S\n", PdoDeviceExtension->DeviceID.Buffer);
|
||||
|
||||
/* Add Instance ID string */
|
||||
Status = PciCreateInstanceIDString(&PdoDeviceExtension->InstanceID, Device);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorStatus = Status;
|
||||
ErrorOccurred = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add Hardware IDs string */
|
||||
Status = PciCreateHardwareIDsString(&PdoDeviceExtension->HardwareIDs, Device);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorStatus = Status;
|
||||
ErrorOccurred = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add Compatible IDs string */
|
||||
Status = PciCreateCompatibleIDsString(&PdoDeviceExtension->CompatibleIDs, Device);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorStatus = Status;
|
||||
ErrorOccurred = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add device description string */
|
||||
Status = PciCreateDeviceDescriptionString(&PdoDeviceExtension->DeviceDescription, Device);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorStatus = Status;
|
||||
ErrorOccurred = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add device location string */
|
||||
Status = PciCreateDeviceLocationString(&PdoDeviceExtension->DeviceLocation, Device);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorStatus = Status;
|
||||
ErrorOccurred = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reference the physical device object. The PnP manager
|
||||
will dereference it again when it is no longer needed */
|
||||
ObReferenceObject(Device->Pdo);
|
||||
|
||||
Relations->Objects[i] = Device->Pdo;
|
||||
|
||||
i++;
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
|
||||
if (ErrorOccurred)
|
||||
{
|
||||
/* FIXME: Cleanup all new PDOs created in this call. Please give me SEH!!! ;-) */
|
||||
/* FIXME: Should IoAttachDeviceToDeviceStack() be undone? */
|
||||
if (PdoDeviceExtension)
|
||||
{
|
||||
RtlFreeUnicodeString(&PdoDeviceExtension->DeviceID);
|
||||
RtlFreeUnicodeString(&PdoDeviceExtension->InstanceID);
|
||||
RtlFreeUnicodeString(&PdoDeviceExtension->HardwareIDs);
|
||||
RtlFreeUnicodeString(&PdoDeviceExtension->CompatibleIDs);
|
||||
RtlFreeUnicodeString(&PdoDeviceExtension->DeviceDescription);
|
||||
RtlFreeUnicodeString(&PdoDeviceExtension->DeviceLocation);
|
||||
}
|
||||
|
||||
ExFreePoolWithTag(Relations, TAG_PCI);
|
||||
return ErrorStatus;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Relations;
|
||||
|
||||
DPRINT("Done\n");
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
FdoStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PCM_RESOURCE_LIST AllocatedResources;
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
|
||||
ULONG FoundBusNumber = FALSE;
|
||||
ULONG i;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
AllocatedResources = IoGetCurrentIrpStackLocation(Irp)->Parameters.StartDevice.AllocatedResources;
|
||||
if (!AllocatedResources)
|
||||
{
|
||||
DPRINT("No allocated resources sent to driver\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (AllocatedResources->Count < 1)
|
||||
{
|
||||
DPRINT("Not enough allocated resources sent to driver\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (AllocatedResources->List[0].PartialResourceList.Version != 1 ||
|
||||
AllocatedResources->List[0].PartialResourceList.Revision != 1)
|
||||
return STATUS_REVISION_MISMATCH;
|
||||
|
||||
ASSERT(DeviceExtension->State == dsStopped);
|
||||
|
||||
/* By default, use the bus number in the resource list header */
|
||||
DeviceExtension->BusNumber = AllocatedResources->List[0].BusNumber;
|
||||
|
||||
for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i++)
|
||||
{
|
||||
ResourceDescriptor = &AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i];
|
||||
switch (ResourceDescriptor->Type)
|
||||
{
|
||||
case CmResourceTypeBusNumber:
|
||||
if (FoundBusNumber || ResourceDescriptor->u.BusNumber.Length != 1)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* Use this one instead */
|
||||
ASSERT(AllocatedResources->List[0].BusNumber == ResourceDescriptor->u.BusNumber.Start);
|
||||
DeviceExtension->BusNumber = ResourceDescriptor->u.BusNumber.Start;
|
||||
DPRINT("Found bus number resource: %lu\n", DeviceExtension->BusNumber);
|
||||
FoundBusNumber = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT("Unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type);
|
||||
}
|
||||
}
|
||||
|
||||
InitializeListHead(&DeviceExtension->DeviceListHead);
|
||||
KeInitializeSpinLock(&DeviceExtension->DeviceListLock);
|
||||
DeviceExtension->DeviceListCount = 0;
|
||||
DeviceExtension->State = dsStarted;
|
||||
|
||||
ExInterlockedInsertTailList(
|
||||
&DriverExtension->BusListHead,
|
||||
&DeviceExtension->ListEntry,
|
||||
&DriverExtension->BusListLock);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*** PUBLIC ******************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
FdoPnpControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle Plug and Play IRPs for the PCI device object
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to functional device object of the PCI driver
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status = Irp->IoStatus.Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
switch (IrpSp->MinorFunction)
|
||||
{
|
||||
#if 0
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
#endif
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
|
||||
break;
|
||||
|
||||
Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp);
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
#if 0
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
#endif
|
||||
case IRP_MN_START_DEVICE:
|
||||
DPRINT("IRP_MN_START_DEVICE received\n");
|
||||
Status = ForwardIrpAndWait(DeviceObject, Irp);
|
||||
if (NT_SUCCESS(Status))
|
||||
Status = FdoStartDevice(DeviceObject, Irp);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
/* We don't support stopping yet */
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
/* We can't fail this one so we fail the QUERY_STOP request that precedes it */
|
||||
break;
|
||||
#if 0
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
|
||||
break;
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
/* Detach the device object from the device stack */
|
||||
IoDetachDevice(DeviceExtension->Ldo);
|
||||
|
||||
/* Delete the device object */
|
||||
IoDeleteDevice(DeviceObject);
|
||||
|
||||
/* Return success */
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_CAPABILITIES:
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
||||
/* Don't print the warning, too much noise */
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("Unknown PNP minor function 0x%x\n", IrpSp->MinorFunction);
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = IoCallDriver(DeviceExtension->Ldo, Irp);
|
||||
|
||||
DPRINT("Leaving. Status 0x%lx\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FdoPowerControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle power management IRPs for the PCI device object
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to functional device object of the PCI driver
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
PoStartNextPowerIrp(Irp);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = PoCallDriver(DeviceExtension->Ldo, Irp);
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
715
drivers/bus/pci/pci.c
Normal file
715
drivers/bus/pci/pci.c
Normal file
|
@ -0,0 +1,715 @@
|
|||
/*
|
||||
* PROJECT: ReactOS PCI Bus driver
|
||||
* FILE: pci.c
|
||||
* PURPOSE: Driver entry
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* UPDATE HISTORY:
|
||||
* 10-09-2001 CSH Created
|
||||
*/
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static DRIVER_DISPATCH PciDispatchDeviceControl;
|
||||
static NTSTATUS NTAPI PciDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
||||
|
||||
static DRIVER_ADD_DEVICE PciAddDevice;
|
||||
static NTSTATUS NTAPI PciAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject);
|
||||
|
||||
static DRIVER_DISPATCH PciPowerControl;
|
||||
static NTSTATUS NTAPI PciPowerControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
||||
|
||||
static DRIVER_DISPATCH PciPnpControl;
|
||||
static NTSTATUS NTAPI PciPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
||||
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
|
||||
// Make the initialization routines discardable, so that they
|
||||
// don't waste space
|
||||
|
||||
#pragma alloc_text(init, DriverEntry)
|
||||
|
||||
#endif /* ALLOC_PRAGMA */
|
||||
|
||||
/*** PUBLIC ******************************************************************/
|
||||
|
||||
PPCI_DRIVER_EXTENSION DriverExtension = NULL;
|
||||
|
||||
/*** PRIVATE *****************************************************************/
|
||||
|
||||
static NTSTATUS
|
||||
NTAPI
|
||||
PciDispatchDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
DPRINT("Called. IRP is at (0x%p)\n", Irp);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
default:
|
||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
|
||||
DPRINT("Completing IRP at 0x%p\n", Irp);
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
NTAPI
|
||||
PciPnpControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle Plug and Play IRPs
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to PDO or FDO
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
DPRINT("IsFDO %u\n", DeviceExtension->IsFDO);
|
||||
|
||||
if (DeviceExtension->IsFDO)
|
||||
{
|
||||
Status = FdoPnpControl(DeviceObject, Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = PdoPnpControl(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
NTAPI
|
||||
PciPowerControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle power management IRPs
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to PDO or FDO
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (DeviceExtension->IsFDO)
|
||||
{
|
||||
Status = FdoPowerControl(DeviceObject, Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = PdoPowerControl(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
NTAPI
|
||||
PciAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_OBJECT Fdo;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
if (PhysicalDeviceObject == NULL)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(FDO_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_BUS_EXTENDER,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
TRUE,
|
||||
&Fdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
|
||||
|
||||
RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
|
||||
|
||||
DeviceExtension->Common.IsFDO = TRUE;
|
||||
|
||||
DeviceExtension->Ldo = IoAttachDeviceToDeviceStack(Fdo,
|
||||
PhysicalDeviceObject);
|
||||
|
||||
DeviceExtension->State = dsStopped;
|
||||
|
||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
//Fdo->Flags |= DO_POWER_PAGABLE;
|
||||
|
||||
DPRINT("Done AddDevice\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
DRIVER_UNLOAD PciUnload;
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PciUnload(
|
||||
IN PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
/* The driver object extension is destroyed by the I/O manager */
|
||||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
UNREFERENCED_PARAMETER(RegistryPath);
|
||||
DPRINT("Peripheral Component Interconnect Bus Driver\n");
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PciDispatchDeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = PciPnpControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_POWER] = PciPowerControl;
|
||||
DriverObject->DriverExtension->AddDevice = PciAddDevice;
|
||||
DriverObject->DriverUnload = PciUnload;
|
||||
|
||||
Status = IoAllocateDriverObjectExtension(DriverObject,
|
||||
DriverObject,
|
||||
sizeof(PCI_DRIVER_EXTENSION),
|
||||
(PVOID*)&DriverExtension);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
RtlZeroMemory(DriverExtension, sizeof(PCI_DRIVER_EXTENSION));
|
||||
|
||||
InitializeListHead(&DriverExtension->BusListHead);
|
||||
KeInitializeSpinLock(&DriverExtension->BusListLock);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PciCreateDeviceIDString(PUNICODE_STRING DeviceID,
|
||||
PPCI_DEVICE Device)
|
||||
{
|
||||
WCHAR Buffer[256];
|
||||
|
||||
swprintf(Buffer,
|
||||
L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
|
||||
Device->PciConfig.VendorID,
|
||||
Device->PciConfig.DeviceID,
|
||||
(Device->PciConfig.u.type0.SubSystemID << 16) +
|
||||
Device->PciConfig.u.type0.SubVendorID,
|
||||
Device->PciConfig.RevisionID);
|
||||
|
||||
return RtlCreateUnicodeString(DeviceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PciCreateInstanceIDString(PUNICODE_STRING InstanceID,
|
||||
PPCI_DEVICE Device)
|
||||
{
|
||||
WCHAR Buffer[3];
|
||||
|
||||
swprintf(Buffer, L"%02X", Device->SlotNumber.u.AsULONG & 0xff);
|
||||
|
||||
return RtlCreateUnicodeString(InstanceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs,
|
||||
PPCI_DEVICE Device)
|
||||
{
|
||||
WCHAR Buffer[256];
|
||||
UNICODE_STRING BufferU;
|
||||
ULONG Index;
|
||||
|
||||
Index = 0;
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
|
||||
Device->PciConfig.VendorID,
|
||||
Device->PciConfig.DeviceID,
|
||||
(Device->PciConfig.u.type0.SubSystemID << 16) +
|
||||
Device->PciConfig.u.type0.SubVendorID,
|
||||
Device->PciConfig.RevisionID);
|
||||
Index++;
|
||||
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
|
||||
Device->PciConfig.VendorID,
|
||||
Device->PciConfig.DeviceID,
|
||||
(Device->PciConfig.u.type0.SubSystemID << 16) +
|
||||
Device->PciConfig.u.type0.SubVendorID);
|
||||
Index++;
|
||||
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
|
||||
Device->PciConfig.VendorID,
|
||||
Device->PciConfig.DeviceID,
|
||||
Device->PciConfig.BaseClass,
|
||||
Device->PciConfig.SubClass,
|
||||
Device->PciConfig.ProgIf);
|
||||
Index++;
|
||||
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
|
||||
Device->PciConfig.VendorID,
|
||||
Device->PciConfig.DeviceID,
|
||||
Device->PciConfig.BaseClass,
|
||||
Device->PciConfig.SubClass);
|
||||
Index++;
|
||||
|
||||
Buffer[Index] = UNICODE_NULL;
|
||||
|
||||
BufferU.Length = BufferU.MaximumLength = (USHORT) Index * sizeof(WCHAR);
|
||||
BufferU.Buffer = Buffer;
|
||||
|
||||
return PciDuplicateUnicodeString(0, &BufferU, HardwareIDs);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs,
|
||||
PPCI_DEVICE Device)
|
||||
{
|
||||
WCHAR Buffer[256];
|
||||
UNICODE_STRING BufferU;
|
||||
ULONG Index;
|
||||
|
||||
Index = 0;
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\VEN_%04X&DEV_%04X&REV_%02X",
|
||||
Device->PciConfig.VendorID,
|
||||
Device->PciConfig.DeviceID,
|
||||
Device->PciConfig.RevisionID);
|
||||
Index++;
|
||||
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\VEN_%04X&DEV_%04X",
|
||||
Device->PciConfig.VendorID,
|
||||
Device->PciConfig.DeviceID);
|
||||
Index++;
|
||||
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\VEN_%04X&CC_%02X%02X%02X",
|
||||
Device->PciConfig.VendorID,
|
||||
Device->PciConfig.BaseClass,
|
||||
Device->PciConfig.SubClass,
|
||||
Device->PciConfig.ProgIf);
|
||||
Index++;
|
||||
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\VEN_%04X&CC_%02X%02X",
|
||||
Device->PciConfig.VendorID,
|
||||
Device->PciConfig.BaseClass,
|
||||
Device->PciConfig.SubClass);
|
||||
Index++;
|
||||
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\VEN_%04X",
|
||||
Device->PciConfig.VendorID);
|
||||
Index++;
|
||||
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\CC_%02X%02X%02X",
|
||||
Device->PciConfig.BaseClass,
|
||||
Device->PciConfig.SubClass,
|
||||
Device->PciConfig.ProgIf);
|
||||
Index++;
|
||||
|
||||
Index += swprintf(&Buffer[Index],
|
||||
L"PCI\\CC_%02X%02X",
|
||||
Device->PciConfig.BaseClass,
|
||||
Device->PciConfig.SubClass);
|
||||
Index++;
|
||||
|
||||
Buffer[Index] = UNICODE_NULL;
|
||||
|
||||
BufferU.Length = BufferU.MaximumLength = (USHORT)Index * sizeof(WCHAR);
|
||||
BufferU.Buffer = Buffer;
|
||||
|
||||
return PciDuplicateUnicodeString(0, &BufferU, CompatibleIDs);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription,
|
||||
PPCI_DEVICE Device)
|
||||
{
|
||||
PCWSTR Description;
|
||||
|
||||
switch (Device->PciConfig.BaseClass)
|
||||
{
|
||||
case PCI_CLASS_PRE_20:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
case PCI_SUBCLASS_PRE_20_VGA:
|
||||
Description = L"VGA device";
|
||||
break;
|
||||
|
||||
default:
|
||||
case PCI_SUBCLASS_PRE_20_NON_VGA:
|
||||
Description = L"PCI device";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_MASS_STORAGE_CTLR:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR:
|
||||
Description = L"SCSI controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_MSC_IDE_CTLR:
|
||||
Description = L"IDE controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_MSC_FLOPPY_CTLR:
|
||||
Description = L"Floppy disk controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_MSC_IPI_CTLR:
|
||||
Description = L"IPI controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_MSC_RAID_CTLR:
|
||||
Description = L"RAID controller";
|
||||
break;
|
||||
|
||||
default:
|
||||
Description = L"Mass storage controller";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_NETWORK_CTLR:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
case PCI_SUBCLASS_NET_ETHERNET_CTLR:
|
||||
Description = L"Ethernet controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_NET_TOKEN_RING_CTLR:
|
||||
Description = L"Token-Ring controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_NET_FDDI_CTLR:
|
||||
Description = L"FDDI controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_NET_ATM_CTLR:
|
||||
Description = L"ATM controller";
|
||||
break;
|
||||
|
||||
default:
|
||||
Description = L"Network controller";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_DISPLAY_CTLR:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
case PCI_SUBCLASS_VID_VGA_CTLR:
|
||||
Description = L"VGA display controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_VID_XGA_CTLR:
|
||||
Description = L"XGA display controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_VID_3D_CTLR:
|
||||
Description = L"Multimedia display controller";
|
||||
break;
|
||||
|
||||
default:
|
||||
Description = L"Other display controller";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_MULTIMEDIA_DEV:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
case PCI_SUBCLASS_MM_VIDEO_DEV:
|
||||
Description = L"Multimedia video device";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_MM_AUDIO_DEV:
|
||||
Description = L"Multimedia audio device";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_MM_TELEPHONY_DEV:
|
||||
Description = L"Multimedia telephony device";
|
||||
break;
|
||||
|
||||
default:
|
||||
Description = L"Other multimedia device";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_MEMORY_CTLR:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
case PCI_SUBCLASS_MEM_RAM:
|
||||
Description = L"PCI Memory";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_MEM_FLASH:
|
||||
Description = L"PCI Flash Memory";
|
||||
break;
|
||||
|
||||
default:
|
||||
Description = L"Other memory controller";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_BRIDGE_DEV:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
case PCI_SUBCLASS_BR_HOST:
|
||||
Description = L"PCI-Host bridge";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_BR_ISA:
|
||||
Description = L"PCI-ISA bridge";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_BR_EISA:
|
||||
Description = L"PCI-EISA bridge";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_BR_MCA:
|
||||
Description = L"PCI-Micro Channel bridge";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_BR_PCI_TO_PCI:
|
||||
Description = L"PCI-PCI bridge";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_BR_PCMCIA:
|
||||
Description = L"PCI-PCMCIA bridge";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_BR_NUBUS:
|
||||
Description = L"PCI-NUBUS bridge";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_BR_CARDBUS:
|
||||
Description = L"PCI-CARDBUS bridge";
|
||||
break;
|
||||
|
||||
default:
|
||||
Description = L"Other bridge device";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_SIMPLE_COMMS_CTLR:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
|
||||
default:
|
||||
Description = L"Communication device";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_BASE_SYSTEM_DEV:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
|
||||
default:
|
||||
Description = L"System device";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_INPUT_DEV:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
|
||||
default:
|
||||
Description = L"Input device";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_DOCKING_STATION:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
|
||||
default:
|
||||
Description = L"Docking station";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_PROCESSOR:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
|
||||
default:
|
||||
Description = L"Processor";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_SERIAL_BUS_CTLR:
|
||||
switch (Device->PciConfig.SubClass)
|
||||
{
|
||||
case PCI_SUBCLASS_SB_IEEE1394:
|
||||
Description = L"FireWire controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_SB_ACCESS:
|
||||
Description = L"ACCESS bus controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_SB_SSA:
|
||||
Description = L"SSA controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_SB_USB:
|
||||
Description = L"USB controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_SB_FIBRE_CHANNEL:
|
||||
Description = L"Fibre Channel controller";
|
||||
break;
|
||||
|
||||
case PCI_SUBCLASS_SB_SMBUS:
|
||||
Description = L"SMBus controller";
|
||||
break;
|
||||
|
||||
default:
|
||||
Description = L"Other serial bus controller";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Description = L"Other PCI Device";
|
||||
break;
|
||||
}
|
||||
|
||||
return RtlCreateUnicodeString(DeviceDescription, Description) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation,
|
||||
PPCI_DEVICE Device)
|
||||
{
|
||||
WCHAR Buffer[256];
|
||||
|
||||
swprintf(Buffer,
|
||||
L"PCI-Bus %lu, Device %u, Function %u",
|
||||
Device->BusNumber,
|
||||
Device->SlotNumber.u.bits.DeviceNumber,
|
||||
Device->SlotNumber.u.bits.FunctionNumber);
|
||||
|
||||
return RtlCreateUnicodeString(DeviceLocation, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
PciDuplicateUnicodeString(
|
||||
IN ULONG Flags,
|
||||
IN PCUNICODE_STRING SourceString,
|
||||
OUT PUNICODE_STRING DestinationString)
|
||||
{
|
||||
if (SourceString == NULL ||
|
||||
DestinationString == NULL ||
|
||||
SourceString->Length > SourceString->MaximumLength ||
|
||||
(SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL) ||
|
||||
Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING ||
|
||||
Flags >= 4)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((SourceString->Length == 0) &&
|
||||
(Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
|
||||
RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
|
||||
{
|
||||
DestinationString->Length = 0;
|
||||
DestinationString->MaximumLength = 0;
|
||||
DestinationString->Buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
USHORT DestMaxLength = SourceString->Length;
|
||||
|
||||
if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
|
||||
DestMaxLength += sizeof(UNICODE_NULL);
|
||||
|
||||
DestinationString->Buffer = ExAllocatePoolWithTag(PagedPool, DestMaxLength, TAG_PCI);
|
||||
if (DestinationString->Buffer == NULL)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
|
||||
DestinationString->Length = SourceString->Length;
|
||||
DestinationString->MaximumLength = DestMaxLength;
|
||||
|
||||
if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
|
||||
DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
181
drivers/bus/pci/pci.h
Normal file
181
drivers/bus/pci/pci.h
Normal file
|
@ -0,0 +1,181 @@
|
|||
#ifndef _PCI_PCH_
|
||||
#define _PCI_PCH_
|
||||
|
||||
#include <ntifs.h>
|
||||
|
||||
#define TAG_PCI '0ICP'
|
||||
|
||||
typedef struct _PCI_DEVICE
|
||||
{
|
||||
// Entry on device list
|
||||
LIST_ENTRY ListEntry;
|
||||
// Physical Device Object of device
|
||||
PDEVICE_OBJECT Pdo;
|
||||
// PCI bus number
|
||||
ULONG BusNumber;
|
||||
// PCI slot number
|
||||
PCI_SLOT_NUMBER SlotNumber;
|
||||
// PCI configuration data
|
||||
PCI_COMMON_CONFIG PciConfig;
|
||||
// Enable memory space
|
||||
BOOLEAN EnableMemorySpace;
|
||||
// Enable I/O space
|
||||
BOOLEAN EnableIoSpace;
|
||||
// Enable bus master
|
||||
BOOLEAN EnableBusMaster;
|
||||
} PCI_DEVICE, *PPCI_DEVICE;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
dsStopped,
|
||||
dsStarted,
|
||||
dsPaused,
|
||||
dsRemoved,
|
||||
dsSurpriseRemoved
|
||||
} PCI_DEVICE_STATE;
|
||||
|
||||
|
||||
typedef struct _COMMON_DEVICE_EXTENSION
|
||||
{
|
||||
// Pointer to device object, this device extension is associated with
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
// Wether this device extension is for an FDO or PDO
|
||||
BOOLEAN IsFDO;
|
||||
// Wether the device is removed
|
||||
BOOLEAN Removed;
|
||||
// Current device power state for the device
|
||||
DEVICE_POWER_STATE DevicePowerState;
|
||||
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
|
||||
|
||||
/* Physical Device Object device extension for a child device */
|
||||
typedef struct _PDO_DEVICE_EXTENSION
|
||||
{
|
||||
// Common device data
|
||||
COMMON_DEVICE_EXTENSION Common;
|
||||
// Functional device object
|
||||
PDEVICE_OBJECT Fdo;
|
||||
// Pointer to PCI Device informations
|
||||
PPCI_DEVICE PciDevice;
|
||||
// Device ID
|
||||
UNICODE_STRING DeviceID;
|
||||
// Instance ID
|
||||
UNICODE_STRING InstanceID;
|
||||
// Hardware IDs
|
||||
UNICODE_STRING HardwareIDs;
|
||||
// Compatible IDs
|
||||
UNICODE_STRING CompatibleIDs;
|
||||
// Textual description of device
|
||||
UNICODE_STRING DeviceDescription;
|
||||
// Textual description of device location
|
||||
UNICODE_STRING DeviceLocation;
|
||||
// Number of interfaces references
|
||||
LONG References;
|
||||
} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
|
||||
|
||||
/* Functional Device Object device extension for the PCI driver device object */
|
||||
typedef struct _FDO_DEVICE_EXTENSION
|
||||
{
|
||||
// Common device data
|
||||
COMMON_DEVICE_EXTENSION Common;
|
||||
// Entry on device list
|
||||
LIST_ENTRY ListEntry;
|
||||
// PCI bus number serviced by this FDO
|
||||
ULONG BusNumber;
|
||||
// Current state of the driver
|
||||
PCI_DEVICE_STATE State;
|
||||
// Namespace device list
|
||||
LIST_ENTRY DeviceListHead;
|
||||
// Number of (not removed) devices in device list
|
||||
ULONG DeviceListCount;
|
||||
// Lock for namespace device list
|
||||
KSPIN_LOCK DeviceListLock;
|
||||
// Lower device object
|
||||
PDEVICE_OBJECT Ldo;
|
||||
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||
|
||||
|
||||
/* Driver extension associated with PCI driver */
|
||||
typedef struct _PCI_DRIVER_EXTENSION
|
||||
{
|
||||
//
|
||||
LIST_ENTRY BusListHead;
|
||||
// Lock for namespace bus list
|
||||
KSPIN_LOCK BusListLock;
|
||||
} PCI_DRIVER_EXTENSION, *PPCI_DRIVER_EXTENSION;
|
||||
|
||||
|
||||
/* We need a global variable to get the driver extension,
|
||||
* because at least InterfacePciDevicePresent has no
|
||||
* other way to get it... */
|
||||
extern PPCI_DRIVER_EXTENSION DriverExtension;
|
||||
|
||||
/* fdo.c */
|
||||
|
||||
NTSTATUS
|
||||
FdoPnpControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
FdoPowerControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
/* pci.c */
|
||||
|
||||
NTSTATUS
|
||||
PciCreateDeviceIDString(
|
||||
PUNICODE_STRING DeviceID,
|
||||
PPCI_DEVICE Device);
|
||||
|
||||
NTSTATUS
|
||||
PciCreateInstanceIDString(
|
||||
PUNICODE_STRING InstanceID,
|
||||
PPCI_DEVICE Device);
|
||||
|
||||
NTSTATUS
|
||||
PciCreateHardwareIDsString(
|
||||
PUNICODE_STRING HardwareIDs,
|
||||
PPCI_DEVICE Device);
|
||||
|
||||
NTSTATUS
|
||||
PciCreateCompatibleIDsString(
|
||||
PUNICODE_STRING HardwareIDs,
|
||||
PPCI_DEVICE Device);
|
||||
|
||||
NTSTATUS
|
||||
PciCreateDeviceDescriptionString(
|
||||
PUNICODE_STRING DeviceDescription,
|
||||
PPCI_DEVICE Device);
|
||||
|
||||
NTSTATUS
|
||||
PciCreateDeviceLocationString(
|
||||
PUNICODE_STRING DeviceLocation,
|
||||
PPCI_DEVICE Device);
|
||||
|
||||
NTSTATUS
|
||||
PciDuplicateUnicodeString(
|
||||
IN ULONG Flags,
|
||||
IN PCUNICODE_STRING SourceString,
|
||||
OUT PUNICODE_STRING DestinationString);
|
||||
|
||||
/* pdo.c */
|
||||
|
||||
NTSTATUS
|
||||
PdoPnpControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
PdoPowerControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath);
|
||||
|
||||
#endif /* _PCI_PCH_ */
|
5
drivers/bus/pci/pci.rc
Normal file
5
drivers/bus/pci/pci.rc
Normal file
|
@ -0,0 +1,5 @@
|
|||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "PCI Bus Driver"
|
||||
#define REACTOS_STR_INTERNAL_NAME "pci"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "pci.sys"
|
||||
#include <reactos/version.rc>
|
299
drivers/bus/pci/pcidef.h
Normal file
299
drivers/bus/pci/pcidef.h
Normal file
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* PCI defines and function prototypes
|
||||
* Copyright 1994, Drew Eckhardt
|
||||
* Copyright 1997--1999 Martin Mares <mj@suse.cz>
|
||||
*
|
||||
* For more information, please consult the following manuals (look at
|
||||
* http://www.pcisig.com/ for how to get them):
|
||||
*
|
||||
* PCI BIOS Specification
|
||||
* PCI Local Bus Specification
|
||||
* PCI to PCI Bridge Specification
|
||||
* PCI System Design Guide
|
||||
*
|
||||
* Ported from linux pci.h to ReactOS by:
|
||||
* Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Under PCI, each device has 256 bytes of configuration address space,
|
||||
* of which the first 64 bytes are standardized as follows:
|
||||
*/
|
||||
#define PCI_VENDOR_ID 0x00 /* 16 bits */
|
||||
#define PCI_DEVICE_ID 0x02 /* 16 bits */
|
||||
#define PCI_COMMAND 0x04 /* 16 bits */
|
||||
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
|
||||
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
|
||||
#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
|
||||
#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
|
||||
#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
|
||||
#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
|
||||
#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
|
||||
#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
|
||||
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
|
||||
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
|
||||
|
||||
#define PCI_STATUS 0x06 /* 16 bits */
|
||||
#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
|
||||
#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
|
||||
#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
|
||||
#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
|
||||
#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
|
||||
#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
|
||||
#define PCI_STATUS_DEVSEL_FAST 0x000
|
||||
#define PCI_STATUS_DEVSEL_MEDIUM 0x200
|
||||
#define PCI_STATUS_DEVSEL_SLOW 0x400
|
||||
#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
|
||||
#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
|
||||
#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
|
||||
#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
|
||||
#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
|
||||
|
||||
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8
|
||||
revision */
|
||||
#define PCI_REVISION_ID 0x08 /* Revision ID */
|
||||
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
|
||||
#define PCI_CLASS_DEVICE 0x0a /* Device class */
|
||||
|
||||
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
|
||||
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
|
||||
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
|
||||
#define PCI_HEADER_TYPE_NORMAL 0
|
||||
#define PCI_HEADER_TYPE_BRIDGE 1
|
||||
#define PCI_HEADER_TYPE_CARDBUS 2
|
||||
|
||||
#define PCI_BIST 0x0f /* 8 bits */
|
||||
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
|
||||
#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
|
||||
#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
|
||||
|
||||
/*
|
||||
* Base addresses specify locations in memory or I/O space.
|
||||
* Decoded size can be determined by writing a value of
|
||||
* 0xffffffff to the register, and reading it back. Only
|
||||
* 1 bits are decoded.
|
||||
*/
|
||||
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
|
||||
#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
|
||||
#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
|
||||
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
|
||||
#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
|
||||
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
|
||||
#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
|
||||
#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
|
||||
#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
|
||||
#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
|
||||
#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
|
||||
#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
|
||||
/* bit 1 is reserved if address_space = 1 */
|
||||
|
||||
/* Header type 0 (normal devices) */
|
||||
#define PCI_CARDBUS_CIS 0x28
|
||||
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
|
||||
#define PCI_SUBSYSTEM_ID 0x2e
|
||||
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
|
||||
#define PCI_ROM_ADDRESS_ENABLE 0x01
|
||||
#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
|
||||
|
||||
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
|
||||
|
||||
/* 0x35-0x3b are reserved */
|
||||
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
|
||||
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
|
||||
#define PCI_MIN_GNT 0x3e /* 8 bits */
|
||||
#define PCI_MAX_LAT 0x3f /* 8 bits */
|
||||
|
||||
/* Header type 1 (PCI-to-PCI bridges) */
|
||||
#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
|
||||
#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
|
||||
#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
|
||||
#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
|
||||
#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
|
||||
#define PCI_IO_LIMIT 0x1d
|
||||
#define PCI_IO_RANGE_TYPE_MASK 0x0f /* I/O bridging type */
|
||||
#define PCI_IO_RANGE_TYPE_16 0x00
|
||||
#define PCI_IO_RANGE_TYPE_32 0x01
|
||||
#define PCI_IO_RANGE_MASK ~0x0f
|
||||
#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
|
||||
#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
|
||||
#define PCI_MEMORY_LIMIT 0x22
|
||||
#define PCI_MEMORY_RANGE_TYPE_MASK 0x0f
|
||||
#define PCI_MEMORY_RANGE_MASK ~0x0f
|
||||
#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
|
||||
#define PCI_PREF_MEMORY_LIMIT 0x26
|
||||
#define PCI_PREF_RANGE_TYPE_MASK 0x0f
|
||||
#define PCI_PREF_RANGE_TYPE_32 0x00
|
||||
#define PCI_PREF_RANGE_TYPE_64 0x01
|
||||
#define PCI_PREF_RANGE_MASK ~0x0f
|
||||
#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
|
||||
#define PCI_PREF_LIMIT_UPPER32 0x2c
|
||||
#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
|
||||
#define PCI_IO_LIMIT_UPPER16 0x32
|
||||
/* 0x34 same as for htype 0 */
|
||||
/* 0x35-0x3b is reserved */
|
||||
#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
|
||||
/* 0x3c-0x3d are same as for htype 0 */
|
||||
#define PCI_BRIDGE_CONTROL 0x3e
|
||||
#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
|
||||
#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
|
||||
#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
|
||||
#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
|
||||
#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
|
||||
#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
|
||||
#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
|
||||
|
||||
/* Header type 2 (CardBus bridges) */
|
||||
#define PCI_CB_CAPABILITY_LIST 0x14
|
||||
/* 0x15 reserved */
|
||||
#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */
|
||||
#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */
|
||||
#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */
|
||||
#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */
|
||||
#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */
|
||||
#define PCI_CB_MEMORY_BASE_0 0x1c
|
||||
#define PCI_CB_MEMORY_LIMIT_0 0x20
|
||||
#define PCI_CB_MEMORY_BASE_1 0x24
|
||||
#define PCI_CB_MEMORY_LIMIT_1 0x28
|
||||
#define PCI_CB_IO_BASE_0 0x2c
|
||||
#define PCI_CB_IO_BASE_0_HI 0x2e
|
||||
#define PCI_CB_IO_LIMIT_0 0x30
|
||||
#define PCI_CB_IO_LIMIT_0_HI 0x32
|
||||
#define PCI_CB_IO_BASE_1 0x34
|
||||
#define PCI_CB_IO_BASE_1_HI 0x36
|
||||
#define PCI_CB_IO_LIMIT_1 0x38
|
||||
#define PCI_CB_IO_LIMIT_1_HI 0x3a
|
||||
#define PCI_CB_IO_RANGE_MASK ~0x03
|
||||
/* 0x3c-0x3d are same as for htype 0 */
|
||||
#define PCI_CB_BRIDGE_CONTROL 0x3e
|
||||
#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */
|
||||
#define PCI_CB_BRIDGE_CTL_SERR 0x02
|
||||
#define PCI_CB_BRIDGE_CTL_ISA 0x04
|
||||
#define PCI_CB_BRIDGE_CTL_VGA 0x08
|
||||
#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
|
||||
#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
|
||||
#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */
|
||||
#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
|
||||
#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
|
||||
#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
|
||||
#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
|
||||
#define PCI_CB_SUBSYSTEM_ID 0x42
|
||||
#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */
|
||||
/* 0x48-0x7f reserved */
|
||||
|
||||
/* Capability lists */
|
||||
|
||||
#define PCI_CAP_LIST_ID 0 /* Capability ID */
|
||||
#define PCI_CAP_ID_PM 0x01 /* Power Management */
|
||||
#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
|
||||
#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
|
||||
#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
|
||||
#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
|
||||
#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
|
||||
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
|
||||
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
|
||||
#define PCI_CAP_SIZEOF 4
|
||||
|
||||
/* Power Management Registers */
|
||||
|
||||
#define PCI_PM_PMC 2 /* PM Capabilities Register */
|
||||
#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
|
||||
#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
|
||||
#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */
|
||||
#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
|
||||
#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxiliary power support mask */
|
||||
#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
|
||||
#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
|
||||
#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
|
||||
#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */
|
||||
#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */
|
||||
#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */
|
||||
#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */
|
||||
#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */
|
||||
#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
|
||||
#define PCI_PM_CTRL 4 /* PM control and status register */
|
||||
#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
|
||||
#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
|
||||
#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
|
||||
#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
|
||||
#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
|
||||
#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
|
||||
#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
|
||||
#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
|
||||
#define PCI_PM_DATA_REGISTER 7 /* (??) */
|
||||
#define PCI_PM_SIZEOF 8
|
||||
|
||||
/* AGP registers */
|
||||
|
||||
#define PCI_AGP_VERSION 2 /* BCD version number */
|
||||
#define PCI_AGP_RFU 3 /* Rest of capability flags */
|
||||
#define PCI_AGP_STATUS 4 /* Status register */
|
||||
#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
|
||||
#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
|
||||
#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
|
||||
#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
|
||||
#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
|
||||
#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
|
||||
#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
|
||||
#define PCI_AGP_COMMAND 8 /* Control register */
|
||||
#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
|
||||
#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
|
||||
#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
|
||||
#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
|
||||
#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
|
||||
#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
|
||||
#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 4x rate */
|
||||
#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 4x rate */
|
||||
#define PCI_AGP_SIZEOF 12
|
||||
|
||||
/* Slot Identification */
|
||||
|
||||
#define PCI_SID_ESR 2 /* Expansion Slot Register */
|
||||
#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
|
||||
#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
|
||||
#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
|
||||
|
||||
/* Message Signalled Interrupts registers */
|
||||
|
||||
#define PCI_MSI_FLAGS 2 /* Various flags */
|
||||
#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
|
||||
#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
|
||||
#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
|
||||
#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
|
||||
#define PCI_MSI_RFU 3 /* Rest of capability flags */
|
||||
#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
|
||||
#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
|
||||
#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
|
||||
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
|
||||
|
||||
/*
|
||||
* The PCI interface treats multi-function devices as independent
|
||||
* devices. The slot/function address of each device is encoded
|
||||
* in a single byte as follows:
|
||||
*
|
||||
* 7:3 = slot
|
||||
* 2:0 = function
|
||||
*/
|
||||
#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
|
||||
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
|
||||
#define PCI_FUNC(devfn) ((devfn) & 0x07)
|
||||
|
||||
|
||||
/*
|
||||
* For PCI devices, the region numbers are assigned this way:
|
||||
*
|
||||
* 0-5 standard PCI regions
|
||||
* 6 expansion ROM
|
||||
* 7-10 bridges: address space assigned to buses behind the bridge
|
||||
*/
|
||||
|
||||
#define PCI_ROM_RESOURCE 6
|
||||
#define PCI_BRIDGE_RESOURCES 7
|
||||
#define PCI_NUM_RESOURCES 11
|
||||
|
||||
#define PCI_REGION_FLAG_MASK 0x0f /* These bits of resource flags tell us the PCI region flags */
|
1681
drivers/bus/pci/pdo.c
Normal file
1681
drivers/bus/pci/pdo.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue