Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.

This commit is contained in:
Colin Finck 2017-10-03 07:45:34 +00:00
parent b94e2d8ca0
commit c2c66aff7d
24198 changed files with 0 additions and 37285 deletions

View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff