mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
Added PCI bus driver skeleton
svn path=/trunk/; revision=2253
This commit is contained in:
parent
1ea7189ed9
commit
9baaca2418
7 changed files with 1847 additions and 0 deletions
458
reactos/drivers/bus/pci/fdo.c
Normal file
458
reactos/drivers/bus/pci/fdo.c
Normal file
|
@ -0,0 +1,458 @@
|
|||
/* $Id: fdo.c,v 1.1 2001/09/16 13:18:24 chorns Exp $
|
||||
*
|
||||
* 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 *****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
FdoLocateChildDevice(
|
||||
PPCI_DEVICE *Device,
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension,
|
||||
PPCI_COMMON_CONFIG PciConfig)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PPCI_DEVICE CurrentDevice;
|
||||
|
||||
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)) {
|
||||
*Device = CurrentDevice;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
|
||||
*Device = NULL;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FdoEnumerateDevices(
|
||||
PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PCI_COMMON_CONFIG PciConfig;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PPCI_DEVICE Device;
|
||||
NTSTATUS Status;
|
||||
ULONG Slot;
|
||||
ULONG Size;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* Mark all devices to be removed. If we don't discover them again during
|
||||
enumeration, assume that they have been surprise removed */
|
||||
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
||||
while (CurrentEntry != &DeviceExtension->DeviceListHead) {
|
||||
Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
|
||||
Device->RemovePending = TRUE;
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
|
||||
DeviceExtension->DeviceListCount = 0;
|
||||
|
||||
/* Enumerate devices on the PCI bus */
|
||||
for (Slot = 0; Slot < 256; Slot++)
|
||||
{
|
||||
Size = PciGetBusData(
|
||||
DeviceExtension->BusNumber,
|
||||
Slot,
|
||||
&PciConfig,
|
||||
0,
|
||||
sizeof(PCI_COMMON_CONFIG));
|
||||
if (Size != 0)
|
||||
{
|
||||
DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n",
|
||||
DeviceExtension->BusNumber,
|
||||
Slot>>3,
|
||||
Slot & 0x07,
|
||||
PciConfig.VendorID,
|
||||
PciConfig.DeviceID);
|
||||
|
||||
Status = FdoLocateChildDevice(&Device, DeviceExtension, &PciConfig);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
Device = (PPCI_DEVICE)ExAllocatePool(PagedPool, sizeof(PCI_DEVICE));
|
||||
if (!Device)
|
||||
{
|
||||
/* FIXME: Cleanup resources for already discovered devices */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlZeroMemory(Device, sizeof(PCI_DEVICE));
|
||||
|
||||
RtlMoveMemory(&Device->PciConfig, &PciConfig, sizeof(PCI_COMMON_CONFIG));
|
||||
|
||||
ExInterlockedInsertTailList(
|
||||
&DeviceExtension->DeviceListHead,
|
||||
&Device->ListEntry,
|
||||
&DeviceExtension->DeviceListLock);
|
||||
}
|
||||
|
||||
/* Don't remove this device */
|
||||
Device->RemovePending = FALSE;
|
||||
|
||||
DeviceExtension->DeviceListCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FdoQueryBusRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_RELATIONS Relations;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PPCI_DEVICE Device;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN ErrorOccurred;
|
||||
NTSTATUS ErrorStatus;
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
ULONG Size;
|
||||
ULONG i;
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
|
||||
(DeviceExtension->DeviceListCount - 1);
|
||||
Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
|
||||
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,
|
||||
0,
|
||||
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_BUS_ENUMERATED_DEVICE;
|
||||
|
||||
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->IsFDO = FALSE;
|
||||
|
||||
PdoDeviceExtension->DeviceObject = Device->Pdo;
|
||||
|
||||
PdoDeviceExtension->DevicePowerState = PowerDeviceD0;
|
||||
|
||||
/* FIXME: Get device properties (Hardware IDs, etc.) */
|
||||
|
||||
swprintf(
|
||||
Buffer,
|
||||
L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
|
||||
Device->PciConfig.VendorID,
|
||||
Device->PciConfig.DeviceID,
|
||||
Device->PciConfig.u.type0.SubSystemID,
|
||||
Device->PciConfig.RevisionID);
|
||||
|
||||
if (!PciCreateUnicodeString(
|
||||
&PdoDeviceExtension->DeviceID,
|
||||
Buffer,
|
||||
PagedPool)) {
|
||||
ErrorOccurred = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT("DeviceID: %S\n", PdoDeviceExtension->DeviceID.Buffer);
|
||||
}
|
||||
|
||||
if (!Device->RemovePending) {
|
||||
/* 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);
|
||||
ExFreePool(PdoDeviceExtension);
|
||||
}
|
||||
|
||||
ExFreePool(Relations);
|
||||
return ErrorStatus;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Relations;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FdoStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
assert(DeviceExtension->State == dsStopped);
|
||||
|
||||
InitializeListHead(&DeviceExtension->DeviceListHead);
|
||||
KeInitializeSpinLock(&DeviceExtension->DeviceListLock);
|
||||
DeviceExtension->DeviceListCount = 0;
|
||||
|
||||
PciBusConfigType = PciGetBusConfigType();
|
||||
|
||||
DPRINT("Bus configuration is %d\n", PciBusConfigType);
|
||||
|
||||
if (PciBusConfigType != pbtUnknown) {
|
||||
/* At least one PCI bus is found */
|
||||
}
|
||||
|
||||
/* FIXME: Find a way to get this information */
|
||||
DeviceExtension->BusNumber = 0;
|
||||
|
||||
DeviceExtension->State = dsStarted;
|
||||
|
||||
//Irp->IoStatus.Information = 0;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FdoSetPower(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (IrpSp->Parameters.Power.Type == DevicePowerState) {
|
||||
/* FIXME: Set device power state for the device */
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
} else {
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/*** 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;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)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:
|
||||
Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp);
|
||||
break;
|
||||
#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;
|
||||
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
#endif
|
||||
case IRP_MN_START_DEVICE:
|
||||
DPRINT("IRP_MN_START_DEVICE received\n");
|
||||
Status = FdoStartDevice(DeviceObject, Irp);
|
||||
break;
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
/* Currently not supported */
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
break;
|
||||
#if 0
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||
|
||||
/*
|
||||
* Do NOT complete the IRP as it will be processed by the lower
|
||||
* device object, which will complete the IRP
|
||||
*/
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = IoCallDriver(DeviceExtension->Ldo, Irp);
|
||||
return Status;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (Status != STATUS_PENDING) {
|
||||
if (Status != STATUS_NOT_IMPLEMENTED)
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\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
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IrpSp->MinorFunction) {
|
||||
case IRP_MN_SET_POWER:
|
||||
Status = FdoSetPower(DeviceObject, Irp, IrpSp);
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status != STATUS_PENDING) {
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
13
reactos/drivers/bus/pci/makefile
Normal file
13
reactos/drivers/bus/pci/makefile
Normal file
|
@ -0,0 +1,13 @@
|
|||
# $Id: makefile,v 1.1 2001/09/16 13:18:24 chorns Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_TYPE = driver
|
||||
|
||||
TARGET_NAME = pci
|
||||
|
||||
TARGET_OBJECTS = fdo.o pci.o pdo.o
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
613
reactos/drivers/bus/pci/pci.c
Normal file
613
reactos/drivers/bus/pci/pci.c
Normal file
|
@ -0,0 +1,613 @@
|
|||
/* $Id: pci.c,v 1.1 2001/09/16 13:18:24 chorns Exp $
|
||||
*
|
||||
* 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>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
|
||||
// Make the initialization routines discardable, so that they
|
||||
// don't waste space
|
||||
|
||||
#pragma alloc_text(init, DriverEntry)
|
||||
|
||||
#endif /* ALLOC_PRAGMA */
|
||||
|
||||
/*** PUBLIC ******************************************************************/
|
||||
|
||||
PCI_BUS_TYPE PciBusConfigType = pbtUnknown;
|
||||
|
||||
|
||||
/*** PRIVATE *****************************************************************/
|
||||
|
||||
static NTSTATUS
|
||||
PciReadConfigUchar(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
PUCHAR Value)
|
||||
{
|
||||
switch (PciBusConfigType)
|
||||
{
|
||||
case pbtType1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
*Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3));
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case pbtType2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
*Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset)));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
PciReadConfigUshort(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
PUSHORT Value)
|
||||
{
|
||||
if ((Offset & 1) != 0)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (PciBusConfigType)
|
||||
{
|
||||
case pbtType1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
*Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 1));
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case pbtType2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
*Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
PciReadConfigUlong(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
PULONG Value)
|
||||
{
|
||||
if ((Offset & 3) != 0)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (PciBusConfigType)
|
||||
{
|
||||
case pbtType1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
*Value = READ_PORT_ULONG((PULONG)0xCFC);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case pbtType2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
*Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
PciWriteConfigUchar(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
UCHAR Value)
|
||||
{
|
||||
switch (PciBusConfigType)
|
||||
{
|
||||
case pbtType1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case pbtType2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
PciWriteConfigUshort(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
USHORT Value)
|
||||
{
|
||||
if ((Offset & 1) != 0)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (PciBusConfigType)
|
||||
{
|
||||
case pbtType1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 1), Value);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case pbtType2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
PciWriteConfigUlong(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
ULONG Value)
|
||||
{
|
||||
if ((Offset & 3) != 0)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (PciBusConfigType)
|
||||
{
|
||||
case pbtType1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
WRITE_PORT_ULONG((PULONG)0xCFC, Value);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case pbtType2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
ULONG
|
||||
PciGetBusData(ULONG BusNumber,
|
||||
ULONG SlotNumber,
|
||||
PVOID Buffer,
|
||||
ULONG Offset,
|
||||
ULONG Length)
|
||||
{
|
||||
PVOID Ptr = Buffer;
|
||||
ULONG Address = Offset;
|
||||
ULONG Len = Length;
|
||||
ULONG Vendor;
|
||||
UCHAR HeaderType;
|
||||
|
||||
#if 0
|
||||
DPRINT(" BusNumber %lu\n", BusNumber);
|
||||
DPRINT(" SlotNumber %lu\n", SlotNumber);
|
||||
DPRINT(" Offset 0x%lx\n", Offset);
|
||||
DPRINT(" Length 0x%lx\n", Length);
|
||||
#endif
|
||||
|
||||
if ((Length == 0) || (PciBusConfigType == 0))
|
||||
return 0;
|
||||
|
||||
/* 0E=PCI_HEADER_TYPE */
|
||||
PciReadConfigUchar(BusNumber,
|
||||
SlotNumber & 0xF8,
|
||||
0x0E,
|
||||
&HeaderType);
|
||||
if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0))
|
||||
return 0;
|
||||
|
||||
PciReadConfigUlong(BusNumber,
|
||||
SlotNumber,
|
||||
0x00,
|
||||
&Vendor);
|
||||
/* some broken boards return 0 if a slot is empty: */
|
||||
if (Vendor == 0xFFFFFFFF || Vendor == 0)
|
||||
return 0;
|
||||
|
||||
if ((Address & 1) && (Len >= 1))
|
||||
{
|
||||
PciReadConfigUchar(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
Ptr);
|
||||
Ptr = Ptr + 1;
|
||||
Address++;
|
||||
Len--;
|
||||
}
|
||||
|
||||
if ((Address & 2) && (Len >= 2))
|
||||
{
|
||||
PciReadConfigUshort(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
Ptr);
|
||||
Ptr = Ptr + 2;
|
||||
Address += 2;
|
||||
Len -= 2;
|
||||
}
|
||||
|
||||
while (Len >= 4)
|
||||
{
|
||||
PciReadConfigUlong(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
Ptr);
|
||||
Ptr = Ptr + 4;
|
||||
Address += 4;
|
||||
Len -= 4;
|
||||
}
|
||||
|
||||
if (Len >= 2)
|
||||
{
|
||||
PciReadConfigUshort(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
Ptr);
|
||||
Ptr = Ptr + 2;
|
||||
Address += 2;
|
||||
Len -= 2;
|
||||
}
|
||||
|
||||
if (Len >= 1)
|
||||
{
|
||||
PciReadConfigUchar(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
Ptr);
|
||||
Ptr = Ptr + 1;
|
||||
Address++;
|
||||
Len--;
|
||||
}
|
||||
|
||||
return Length - Len;
|
||||
}
|
||||
|
||||
|
||||
ULONG
|
||||
PciSetBusData(ULONG BusNumber,
|
||||
ULONG SlotNumber,
|
||||
PVOID Buffer,
|
||||
ULONG Offset,
|
||||
ULONG Length)
|
||||
{
|
||||
PVOID Ptr = Buffer;
|
||||
ULONG Address = Offset;
|
||||
ULONG Len = Length;
|
||||
ULONG Vendor;
|
||||
UCHAR HeaderType;
|
||||
|
||||
#if 0
|
||||
DPRINT(" BusNumber %lu\n", BusNumber);
|
||||
DPRINT(" SlotNumber %lu\n", SlotNumber);
|
||||
DPRINT(" Offset 0x%lx\n", Offset);
|
||||
DPRINT(" Length 0x%lx\n", Length);
|
||||
#endif
|
||||
|
||||
if ((Length == 0) || (PciBusConfigType == 0))
|
||||
return 0;
|
||||
|
||||
/* 0E=PCI_HEADER_TYPE */
|
||||
PciReadConfigUchar(BusNumber,
|
||||
SlotNumber & 0xF8,
|
||||
0x0E,
|
||||
&HeaderType);
|
||||
if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0))
|
||||
return 0;
|
||||
|
||||
PciReadConfigUlong(BusNumber,
|
||||
SlotNumber,
|
||||
0x00,
|
||||
&Vendor);
|
||||
/* some broken boards return 0 if a slot is empty: */
|
||||
if (Vendor == 0xFFFFFFFF || Vendor == 0)
|
||||
return 0;
|
||||
|
||||
if ((Address & 1) && (Len >= 1))
|
||||
{
|
||||
PciWriteConfigUchar(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
*(PUCHAR)Ptr);
|
||||
Ptr = Ptr + 1;
|
||||
Address++;
|
||||
Len--;
|
||||
}
|
||||
|
||||
if ((Address & 2) && (Len >= 2))
|
||||
{
|
||||
PciWriteConfigUshort(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
*(PUSHORT)Ptr);
|
||||
Ptr = Ptr + 2;
|
||||
Address += 2;
|
||||
Len -= 2;
|
||||
}
|
||||
|
||||
while (Len >= 4)
|
||||
{
|
||||
PciWriteConfigUlong(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
*(PULONG)Ptr);
|
||||
Ptr = Ptr + 4;
|
||||
Address += 4;
|
||||
Len -= 4;
|
||||
}
|
||||
|
||||
if (Len >= 2)
|
||||
{
|
||||
PciWriteConfigUshort(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
*(PUSHORT)Ptr);
|
||||
Ptr = Ptr + 2;
|
||||
Address += 2;
|
||||
Len -= 2;
|
||||
}
|
||||
|
||||
if (Len >= 1)
|
||||
{
|
||||
PciWriteConfigUchar(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
*(PUCHAR)Ptr);
|
||||
Ptr = Ptr + 1;
|
||||
Address++;
|
||||
Len--;
|
||||
}
|
||||
|
||||
return Length - Len;
|
||||
}
|
||||
|
||||
|
||||
PCI_BUS_TYPE
|
||||
PciGetBusConfigType(VOID)
|
||||
{
|
||||
ULONG Value;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DPRINT("Checking configuration type 1:\n");
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01);
|
||||
Value = READ_PORT_ULONG((PULONG)0xCF8);
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000);
|
||||
if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000)
|
||||
{
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, Value);
|
||||
DPRINT(" Success!\n");
|
||||
return pbtType1;
|
||||
}
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, Value);
|
||||
DPRINT(" Unsuccessful!\n");
|
||||
|
||||
DPRINT("Checking configuration type 2:\n");
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00);
|
||||
if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 &&
|
||||
READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00)
|
||||
{
|
||||
DPRINT(" Success!\n");
|
||||
return pbtType2;
|
||||
}
|
||||
DPRINT(" Unsuccessful!\n");
|
||||
|
||||
DPRINT("No pci bus found!\n");
|
||||
return pbtUnknown;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PciDispatchDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called. IRP is at (0x%X)\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%X\n", Irp);
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
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 %d\n", DeviceExtension->IsFDO);
|
||||
|
||||
if (DeviceExtension->IsFDO) {
|
||||
Status = FdoPnpControl(DeviceObject, Irp);
|
||||
} else {
|
||||
Status = PdoPnpControl(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PciAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_OBJECT Fdo;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
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->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;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
DbgPrint("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;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
PciCreateUnicodeString(
|
||||
PUNICODE_STRING Destination,
|
||||
PWSTR Source,
|
||||
POOL_TYPE PoolType)
|
||||
{
|
||||
ULONG Length;
|
||||
|
||||
if (!Source)
|
||||
{
|
||||
RtlInitUnicodeString(Destination, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Length = (wcslen(Source) + 1) * sizeof(WCHAR);
|
||||
|
||||
Destination->Buffer = ExAllocatePool(PoolType, Length);
|
||||
|
||||
if (Destination->Buffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(Destination->Buffer, Source, Length);
|
||||
|
||||
Destination->MaximumLength = Length;
|
||||
|
||||
Destination->Length = Length - sizeof(WCHAR);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
129
reactos/drivers/bus/pci/pci.h
Normal file
129
reactos/drivers/bus/pci/pci.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/* $Id: pci.h,v 1.1 2001/09/16 13:18:24 chorns Exp $ */
|
||||
|
||||
#ifndef __PCI_H
|
||||
#define __PCI_H
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <pcidef.h>
|
||||
|
||||
|
||||
typedef enum {
|
||||
pbtUnknown = 0,
|
||||
pbtType1,
|
||||
pbtType2,
|
||||
} PCI_BUS_TYPE;
|
||||
|
||||
|
||||
typedef struct _PCI_DEVICE
|
||||
{
|
||||
// Entry on device list
|
||||
LIST_ENTRY ListEntry;
|
||||
// Physical Device Object of device
|
||||
PDEVICE_OBJECT Pdo;
|
||||
// PCI configuration data
|
||||
PCI_COMMON_CONFIG PciConfig;
|
||||
// Flag used during enumeration to locate removed devices
|
||||
BOOLEAN RemovePending;
|
||||
} 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;
|
||||
} __attribute((packed)) 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;
|
||||
// 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 DeviceText;
|
||||
// Textual description of device
|
||||
UNICODE_STRING DeviceTextLocation;
|
||||
} __attribute((packed)) 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;
|
||||
// Physical Device Object
|
||||
PDEVICE_OBJECT Pdo;
|
||||
// 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;
|
||||
// PCI bus number
|
||||
ULONG BusNumber;
|
||||
// Lower device object
|
||||
PDEVICE_OBJECT Ldo;
|
||||
} __attribute((packed)) FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||
|
||||
|
||||
/* fdo.c */
|
||||
|
||||
NTSTATUS
|
||||
FdoPnpControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
FdoPowerControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
/* pci.c */
|
||||
|
||||
extern PCI_BUS_TYPE PciBusConfigType;
|
||||
|
||||
PCI_BUS_TYPE
|
||||
PciGetBusConfigType(VOID);
|
||||
|
||||
BOOLEAN
|
||||
PciCreateUnicodeString(
|
||||
PUNICODE_STRING Destination,
|
||||
PWSTR Source,
|
||||
POOL_TYPE PoolType);
|
||||
|
||||
/* pdo.c */
|
||||
|
||||
NTSTATUS
|
||||
PdoPnpControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
PdoPowerControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
#endif /* __PCI_H */
|
38
reactos/drivers/bus/pci/pci.rc
Normal file
38
reactos/drivers/bus/pci/pci.rc
Normal file
|
@ -0,0 +1,38 @@
|
|||
|
||||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "PCI Bus Driver\0"
|
||||
VALUE "FileVersion", "0.0.0\0"
|
||||
VALUE "InternalName", "pci\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "pci.sys\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
354
reactos/drivers/bus/pci/pcidef.h
Normal file
354
reactos/drivers/bus/pci/pcidef.h
Normal file
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
* $Id: pcidef.h,v 1.1 2001/09/16 13:18:24 chorns Exp $
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#ifndef _PCIDEF_H
|
||||
#define _PCIDEF_H
|
||||
|
||||
/*
|
||||
* 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 /* Auxilliary 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 */
|
||||
|
||||
|
||||
|
||||
#define PCI_TYPE0_ADDRESSES 6
|
||||
#define PCI_TYPE1_ADDRESSES 2
|
||||
|
||||
typedef struct _PCI_COMMON_CONFIG
|
||||
{
|
||||
USHORT VendorID; // (ro)
|
||||
USHORT DeviceID; // (ro)
|
||||
USHORT Command; // Device control
|
||||
USHORT Status;
|
||||
UCHAR RevisionID; // (ro)
|
||||
UCHAR ProgIf; // (ro)
|
||||
UCHAR SubClass; // (ro)
|
||||
UCHAR BaseClass; // (ro)
|
||||
UCHAR CacheLineSize; // (ro+)
|
||||
UCHAR LatencyTimer; // (ro+)
|
||||
UCHAR HeaderType; // (ro)
|
||||
UCHAR BIST; // Built in self test
|
||||
union
|
||||
{
|
||||
struct _PCI_HEADER_TYPE_0
|
||||
{
|
||||
ULONG BaseAddresses[PCI_TYPE0_ADDRESSES];
|
||||
ULONG CIS;
|
||||
USHORT SubVendorID;
|
||||
USHORT SubSystemID;
|
||||
ULONG ROMBaseAddress;
|
||||
UCHAR Capabilities;
|
||||
UCHAR Reserved2[3];
|
||||
ULONG Reserved3;
|
||||
UCHAR InterruptLine; //
|
||||
UCHAR InterruptPin; // (ro)
|
||||
UCHAR MinimumGrant; /* read-only */
|
||||
UCHAR MaximumLatency; /* read-only */
|
||||
} type0;
|
||||
} u;
|
||||
UCHAR DeviceSpecific[192];
|
||||
} __attribute__((packed)) PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
|
||||
|
||||
|
||||
#define CONFIG_CMD(bus, device_fn, where) \
|
||||
(0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
|
||||
|
||||
#define IOADDR(devfn, where) \
|
||||
((0xC000 | ((devfn & 0x78) << 5)) + where)
|
||||
|
||||
#define FUNC(devfn) \
|
||||
(((devfn & 7) << 1) | 0xf0)
|
||||
|
||||
#endif /* _PCIDEF_H */
|
242
reactos/drivers/bus/pci/pdo.c
Normal file
242
reactos/drivers/bus/pci/pdo.c
Normal file
|
@ -0,0 +1,242 @@
|
|||
/* $Id: pdo.c,v 1.1 2001/09/16 13:18:24 chorns Exp $
|
||||
*
|
||||
* PROJECT: ReactOS PCI bus driver
|
||||
* FILE: pdo.c
|
||||
* PURPOSE: Child 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 *****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
PdoQueryId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION DeviceExtension;
|
||||
UNICODE_STRING String;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
// Irp->IoStatus.Information = 0;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
RtlInitUnicodeString(&String, NULL);
|
||||
|
||||
switch (IrpSp->Parameters.QueryId.IdType) {
|
||||
case BusQueryDeviceID:
|
||||
Status = PciCreateUnicodeString(
|
||||
&String,
|
||||
DeviceExtension->DeviceID.Buffer,
|
||||
PagedPool);
|
||||
|
||||
DPRINT("DeviceID: %S\n", String.Buffer);
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
|
||||
break;
|
||||
|
||||
case BusQueryHardwareIDs:
|
||||
case BusQueryCompatibleIDs:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case BusQueryInstanceID:
|
||||
Status = PciCreateUnicodeString(
|
||||
&String,
|
||||
L"0000",
|
||||
PagedPool);
|
||||
|
||||
DPRINT("InstanceID: %S\n", String.Buffer);
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
|
||||
break;
|
||||
|
||||
case BusQueryDeviceSerialNumber:
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PdoSetPower(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (IrpSp->Parameters.Power.Type == DevicePowerState) {
|
||||
Status = STATUS_SUCCESS;
|
||||
switch (IrpSp->Parameters.Power.State.SystemState) {
|
||||
default:
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
} else {
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/*** PUBLIC ******************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
PdoPnpControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle Plug and Play IRPs for the child device
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to physical device object of the child device
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
Status = Irp->IoStatus.Status;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IrpSp->MinorFunction) {
|
||||
#if 0
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
|
||||
break;
|
||||
|
||||
case IRP_MN_EJECT:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_BUS_INFORMATION:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_CAPABILITIES:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
/* FIXME: Possibly handle for RemovalRelations */
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_DEVICE_TEXT:
|
||||
break;
|
||||
#endif
|
||||
case IRP_MN_QUERY_ID:
|
||||
Status = PdoQueryId(DeviceObject, Irp, IrpSp);
|
||||
break;
|
||||
#if 0
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_RESOURCES:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_SET_LOCK:
|
||||
break;
|
||||
|
||||
case IRP_MN_START_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status != STATUS_PENDING) {
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
PdoPowerControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle power management IRPs for the child device
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to physical device object of the child device
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IrpSp->MinorFunction) {
|
||||
case IRP_MN_SET_POWER:
|
||||
Status = PdoSetPower(DeviceObject, Irp, IrpSp);
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status != STATUS_PENDING) {
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Reference in a new issue