mirror of
https://github.com/reactos/reactos.git
synced 2024-10-31 20:02:55 +00:00
Add config interface start (PciReadWriteConfigSpace, PciReadSlotConfig)
Add PDO_EXTENSION structure and PCI_FUNCTION_RESOURCES, now delete #if0 in old code since PDO_EXTENSION is now exist defintion Add ID Class/Subclass to description functions (PciGetDeviceDescriptionMessage, PciGetDescriptionMessage), use pciclass.mc from sir_richard New debug: PciDebugDumpCommonConfig Implement IRP_MN_QUERY_DEVICE_RELATIONS with PciFdoIrpQueryDeviceRelations and PciQueryDeviceRelations Begin PciScanBus, now just dump all found device with no more work (0 QDR return) svn path=/trunk/; revision=48091
This commit is contained in:
parent
4234345b03
commit
f43651e238
|
@ -38,6 +38,7 @@ NTAPI
|
|||
PciInitializeArbiters(IN PPCI_FDO_EXTENSION FdoExtension)
|
||||
{
|
||||
PPCI_INTERFACE CurrentInterface, *Interfaces;
|
||||
PPCI_PDO_EXTENSION PdoExtension;
|
||||
PPCI_ARBITER_INSTANCE ArbiterInterface;
|
||||
NTSTATUS Status;
|
||||
PCI_SIGNATURE ArbiterType;
|
||||
|
@ -49,19 +50,17 @@ PciInitializeArbiters(IN PPCI_FDO_EXTENSION FdoExtension)
|
|||
/* Check if this is the extension for the Root PCI Bus */
|
||||
if (!PCI_IS_ROOT_FDO(FdoExtension))
|
||||
{
|
||||
#if 0 // at next sync when PDO add
|
||||
/* Get the PDO extension */
|
||||
PdoExtension = FdoExtension->PhysicalDeviceObject->DeviceExtension;
|
||||
ASSERT_PDO(PdoExtension);
|
||||
|
||||
/* Skip this bus if it does subtractive decode */
|
||||
if (PdoExtension->Substractive)
|
||||
if (PdoExtension->Dependent.type1.SubtractiveDecode)
|
||||
{
|
||||
DPRINT1("PCI Not creating arbiters for subtractive bus %d\n",
|
||||
PdoExtension->Substractive);
|
||||
PdoExtension->Dependent.type1.SubtractiveDecode);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Query all the registered arbiter interfaces */
|
||||
|
@ -127,7 +126,7 @@ NTAPI
|
|||
PciInitializeArbiterRanges(IN PPCI_FDO_EXTENSION DeviceExtension,
|
||||
IN PCM_RESOURCE_LIST Resources)
|
||||
{
|
||||
//PPCI_PDO_EXTENSION PdoExtension;
|
||||
PPCI_PDO_EXTENSION PdoExtension;
|
||||
CM_RESOURCE_TYPE DesiredType;
|
||||
PVOID Instance;
|
||||
PCI_SIGNATURE ArbiterType;
|
||||
|
@ -144,10 +143,9 @@ PciInitializeArbiterRanges(IN PPCI_FDO_EXTENSION DeviceExtension,
|
|||
if (!PCI_IS_ROOT_FDO(DeviceExtension))
|
||||
{
|
||||
/* Grab the PDO */
|
||||
#if 0 // when pdo support
|
||||
PdoExtension = (PPCI_PDO_EXTENSION)DeviceExtension->PhysicalDeviceObject->DeviceExtension;
|
||||
ASSERT(PdoExtension->ExtensionType == PciPdoExtensionType);
|
||||
#endif
|
||||
|
||||
/* Multiple FDOs are not yet supported */
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
|
|
|
@ -104,7 +104,7 @@ PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation,
|
|||
IN PPCI_FDO_EXTENSION DeviceExtension,
|
||||
IN USHORT MaxMinor)
|
||||
{
|
||||
//PPCI_PDO_EXTENSION PdoDeviceExtension;
|
||||
PPCI_PDO_EXTENSION PdoDeviceExtension;
|
||||
ULONG BreakMask, DebugLevel = 0;
|
||||
PCHAR IrpString;
|
||||
|
||||
|
@ -147,7 +147,7 @@ PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation,
|
|||
{
|
||||
DebugLevel = 0x200;
|
||||
}
|
||||
#if 0 // after commit PDO support
|
||||
|
||||
/* For a PDO, print out the bus, device, and function number */
|
||||
PdoDeviceExtension = (PVOID)DeviceExtension;
|
||||
DPRINT1("PDO(b=0x%x, d=0x%x, f=0x%x)<-%s\n",
|
||||
|
@ -155,7 +155,6 @@ PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation,
|
|||
PdoDeviceExtension->Slot.u.bits.DeviceNumber,
|
||||
PdoDeviceExtension->Slot.u.bits.FunctionNumber,
|
||||
IrpString);
|
||||
#endif
|
||||
}
|
||||
else if (DeviceExtension->ExtensionType == PciFdoExtensionType)
|
||||
{
|
||||
|
@ -181,4 +180,18 @@ PciDebugIrpDispatchDisplay(IN PIO_STACK_LOCATION IoStackLocation,
|
|||
return ((1 << IoStackLocation->MinorFunction) & BreakMask);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData)
|
||||
{
|
||||
USHORT i;
|
||||
|
||||
/* Loop the PCI header */
|
||||
for (i = 0; i < PCI_COMMON_HDR_LENGTH; i += 4)
|
||||
{
|
||||
/* Dump each DWORD and its offset */
|
||||
DPRINT1(" %02x - %08x\n", i, *(PULONG)((ULONG_PTR)PciData + i));
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -16,4 +16,205 @@
|
|||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PciScanBus(IN PPCI_FDO_EXTENSION DeviceExtension)
|
||||
{
|
||||
ULONG MaxDevice = PCI_MAX_DEVICES;
|
||||
ULONG i, j, k;
|
||||
UCHAR Buffer[PCI_COMMON_HDR_LENGTH];
|
||||
PPCI_COMMON_HEADER PciData = (PVOID)Buffer;
|
||||
PCI_SLOT_NUMBER PciSlot;
|
||||
PWCHAR DescriptionText;
|
||||
DPRINT1("PCI Scan Bus: FDO Extension @ 0x%x, Base Bus = 0x%x\n",
|
||||
DeviceExtension, DeviceExtension->BaseBus);
|
||||
|
||||
/* Is this the root FDO? */
|
||||
if (!PCI_IS_ROOT_FDO(DeviceExtension))
|
||||
{
|
||||
/* Other FDOs are not currently supported */
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
/* Loop every device on the bus */
|
||||
PciSlot.u.bits.Reserved = 0;
|
||||
i = DeviceExtension->BaseBus;
|
||||
for (j = 0; j < MaxDevice; j++)
|
||||
{
|
||||
/* Loop every function of each device */
|
||||
PciSlot.u.bits.DeviceNumber = j;
|
||||
for (k = 0; k < PCI_MAX_FUNCTION; k++)
|
||||
{
|
||||
/* Build the final slot structure */
|
||||
PciSlot.u.bits.FunctionNumber = k;
|
||||
|
||||
/* Read the vendor for this slot */
|
||||
PciReadSlotConfig(DeviceExtension,
|
||||
PciSlot,
|
||||
PciData,
|
||||
0,
|
||||
sizeof(USHORT));
|
||||
|
||||
/* Skip invalid device */
|
||||
if (PciData->VendorID == PCI_INVALID_VENDORID) continue;
|
||||
|
||||
/* Now read the whole header */
|
||||
PciReadSlotConfig(DeviceExtension,
|
||||
PciSlot,
|
||||
&PciData->DeviceID,
|
||||
sizeof(USHORT),
|
||||
PCI_COMMON_HDR_LENGTH - sizeof(USHORT));
|
||||
|
||||
/* Dump device that was found */
|
||||
DPRINT1("Scan Found Device 0x%x (b=0x%x, d=0x%x, f=0x%x)\n",
|
||||
PciSlot.u.AsULONG,
|
||||
i,
|
||||
j,
|
||||
k);
|
||||
|
||||
/* Dump the device's header */
|
||||
PciDebugDumpCommonConfig(PciData);
|
||||
|
||||
/* Find description for this device for the debugger's sake */
|
||||
DescriptionText = PciGetDeviceDescriptionMessage(PciData->BaseClass,
|
||||
PciData->SubClass);
|
||||
DPRINT1("Device Description \"%S\".\n", DescriptionText ? DescriptionText : L"(NULL)");
|
||||
if (DescriptionText) ExFreePoolWithTag(DescriptionText, 0);
|
||||
|
||||
/* Check if there is an ACPI Watchdog Table */
|
||||
if (WdTable)
|
||||
{
|
||||
/* Check if this PCI device is the ACPI Watchdog Device... */
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Enumeration is completed */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PciQueryDeviceRelations(IN PPCI_FDO_EXTENSION DeviceExtension,
|
||||
IN OUT PDEVICE_RELATIONS *pDeviceRelations)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PPCI_PDO_EXTENSION PdoExtension;
|
||||
ULONG PdoCount = 0;
|
||||
PDEVICE_RELATIONS DeviceRelations, NewRelations;
|
||||
SIZE_T Size;
|
||||
PDEVICE_OBJECT DeviceObject, *ObjectArray;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Make sure the FDO is started */
|
||||
ASSERT(DeviceExtension->DeviceState == PciStarted);
|
||||
|
||||
/* Synchronize while we enumerate the bus */
|
||||
Status = PciBeginStateTransition(DeviceExtension, PciSynchronizedOperation);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Scan all children PDO */
|
||||
for (PdoExtension = DeviceExtension->ChildPdoList;
|
||||
PdoExtension;
|
||||
PdoExtension = PdoExtension->Next)
|
||||
{
|
||||
/* Invalidate them */
|
||||
PdoExtension->NotPresent = TRUE;
|
||||
}
|
||||
|
||||
/* Scan the PCI Bus */
|
||||
Status = PciScanBus(DeviceExtension);
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
|
||||
/* Enumerate all children PDO again */
|
||||
for (PdoExtension = DeviceExtension->ChildPdoList;
|
||||
PdoExtension;
|
||||
PdoExtension = PdoExtension->Next)
|
||||
{
|
||||
/* Check for PDOs that are still invalidated */
|
||||
if (PdoExtension->NotPresent)
|
||||
{
|
||||
/* This means this PDO existed before, but not anymore */
|
||||
PdoExtension->ReportedMissing = TRUE;
|
||||
DPRINT1("PCI - Old device (pdox) %08x not found on rescan.\n",
|
||||
PdoExtension);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increase count of detected PDOs */
|
||||
PdoCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the current relations and add the newly discovered relations */
|
||||
DeviceRelations = *pDeviceRelations;
|
||||
Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) +
|
||||
PdoCount * sizeof(PDEVICE_OBJECT);
|
||||
if (DeviceRelations) Size += sizeof(PDEVICE_OBJECT) * DeviceRelations->Count;
|
||||
|
||||
/* Allocate the device relations */
|
||||
NewRelations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(0, Size, 'BicP');
|
||||
if (!NewRelations)
|
||||
{
|
||||
/* Out of space, cancel the operation */
|
||||
PciCancelStateTransition(DeviceExtension, PciSynchronizedOperation);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Check if there were any older relations */
|
||||
NewRelations->Count = 0;
|
||||
if (DeviceRelations)
|
||||
{
|
||||
/* Copy the old relations into the new buffer, then free the old one */
|
||||
RtlCopyMemory(NewRelations,
|
||||
DeviceRelations,
|
||||
FIELD_OFFSET(DEVICE_RELATIONS, Objects) +
|
||||
DeviceRelations->Count * sizeof(PDEVICE_OBJECT));
|
||||
ExFreePoolWithTag(DeviceRelations, 0);
|
||||
}
|
||||
|
||||
/* Print out that we're ready to dump relations */
|
||||
DPRINT1("PCI QueryDeviceRelations/BusRelations FDOx %08x (bus 0x%02x)\n",
|
||||
DeviceExtension,
|
||||
DeviceExtension->BaseBus);
|
||||
|
||||
/* Loop the current PDO children and the device relation object array */
|
||||
PdoExtension = DeviceExtension->ChildPdoList;
|
||||
ObjectArray = &NewRelations->Objects[NewRelations->Count];
|
||||
while (PdoExtension)
|
||||
{
|
||||
/* Dump this relation */
|
||||
DPRINT1(" QDR PDO %08x (x %08x)%s\n",
|
||||
PdoExtension->PhysicalDeviceObject,
|
||||
PdoExtension,
|
||||
PdoExtension->NotPresent ?
|
||||
"<Omitted, device flaged not present>" : "");
|
||||
|
||||
/* Is this PDO present? */
|
||||
if (!PdoExtension->NotPresent)
|
||||
{
|
||||
/* Reference it and add it to the array */
|
||||
DeviceObject = PdoExtension->PhysicalDeviceObject;
|
||||
ObfReferenceObject(DeviceObject);
|
||||
*ObjectArray++ = DeviceObject;
|
||||
}
|
||||
|
||||
/* Go to the next PDO */
|
||||
PdoExtension = PdoExtension->Next;
|
||||
}
|
||||
|
||||
/* Terminate dumping the relations */
|
||||
DPRINT1(" QDR Total PDO count = %d (%d already in list)\n",
|
||||
NewRelations->Count + PdoCount,
|
||||
NewRelations->Count);
|
||||
|
||||
/* Return the final count and the new buffer */
|
||||
NewRelations->Count += PdoCount;
|
||||
*pDeviceRelations = NewRelations;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -193,9 +193,25 @@ PciFdoIrpQueryDeviceRelations(IN PIRP Irp,
|
|||
IN PIO_STACK_LOCATION IoStackLocation,
|
||||
IN PPCI_FDO_EXTENSION DeviceExtension)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Are bus relations being queried? */
|
||||
if (IoStackLocation->Parameters.QueryDeviceRelations.Type != BusRelations)
|
||||
{
|
||||
/* The FDO is a bus, so only bus relations can be obtained */
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Scan the PCI bus and build the device relations for the caller */
|
||||
Status = PciQueryDeviceRelations(DeviceExtension,
|
||||
(PDEVICE_RELATIONS*)
|
||||
&Irp->IoStatus.Information);
|
||||
}
|
||||
|
||||
/* Return the enumeration status back */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -47,7 +47,6 @@ agpintrf_Constructor(IN PVOID DeviceExtension,
|
|||
IN USHORT Size,
|
||||
IN PINTERFACE Interface)
|
||||
{
|
||||
#if 0 // when have PDO commit
|
||||
PPCI_PDO_EXTENSION PdoExtension = (PPCI_PDO_EXTENSION)DeviceExtension;
|
||||
|
||||
/* Only AGP bridges are supported (which are PCI-to-PCI Bridge Devices) */
|
||||
|
@ -57,7 +56,6 @@ agpintrf_Constructor(IN PVOID DeviceExtension,
|
|||
/* Fail any other PDO */
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Not yet implemented */
|
||||
UNIMPLEMENTED;
|
||||
|
|
|
@ -189,6 +189,93 @@ typedef struct _PCI_FDO_EXTENSION
|
|||
LONG BusHackFlags;
|
||||
} PCI_FDO_EXTENSION, *PPCI_FDO_EXTENSION;
|
||||
|
||||
typedef struct _PCI_FUNCTION_RESOURCES
|
||||
{
|
||||
IO_RESOURCE_DESCRIPTOR Limit[7];
|
||||
CM_PARTIAL_RESOURCE_DESCRIPTOR Current[7];
|
||||
} PCI_FUNCTION_RESOURCES, *PPCI_FUNCTION_RESOURCES;
|
||||
|
||||
typedef union _PCI_HEADER_TYPE_DEPENDENT
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Spare[4];
|
||||
} type0;
|
||||
struct
|
||||
{
|
||||
UCHAR PrimaryBus;
|
||||
UCHAR SecondaryBus;
|
||||
UCHAR SubordinateBus;
|
||||
UCHAR SubtractiveDecode:1;
|
||||
UCHAR IsaBitSet:1;
|
||||
UCHAR VgaBitSet:1;
|
||||
UCHAR WeChangedBusNumbers:1;
|
||||
UCHAR IsaBitRequired:1;
|
||||
} type1;
|
||||
struct
|
||||
{
|
||||
UCHAR Spare[4];
|
||||
} type2;
|
||||
} PCI_HEADER_TYPE_DEPENDENT, *PPCI_HEADER_TYPE_DEPENDENT;
|
||||
|
||||
typedef struct _PCI_PDO_EXTENSION
|
||||
{
|
||||
PVOID Next;
|
||||
ULONG ExtensionType;
|
||||
struct _PCI_MJ_DISPATCH_TABLE *IrpDispatchTable;
|
||||
BOOLEAN DeviceState;
|
||||
BOOLEAN TentativeNextState;
|
||||
|
||||
KEVENT SecondaryExtLock;
|
||||
PCI_SLOT_NUMBER Slot;
|
||||
PDEVICE_OBJECT PhysicalDeviceObject;
|
||||
PPCI_FDO_EXTENSION ParentFdoExtension;
|
||||
SINGLE_LIST_ENTRY SecondaryExtension;
|
||||
LONG BusInterfaceReferenceCount;
|
||||
LONG AgpInterfaceReferenceCount;
|
||||
USHORT VendorId;
|
||||
USHORT DeviceId;
|
||||
USHORT SubsystemVendorId;
|
||||
USHORT SubsystemId;
|
||||
BOOLEAN RevisionId;
|
||||
BOOLEAN ProgIf;
|
||||
BOOLEAN SubClass;
|
||||
BOOLEAN BaseClass;
|
||||
BOOLEAN AdditionalResourceCount;
|
||||
BOOLEAN AdjustedInterruptLine;
|
||||
BOOLEAN InterruptPin;
|
||||
BOOLEAN RawInterruptLine;
|
||||
BOOLEAN CapabilitiesPtr;
|
||||
BOOLEAN SavedLatencyTimer;
|
||||
BOOLEAN SavedCacheLineSize;
|
||||
BOOLEAN HeaderType;
|
||||
BOOLEAN NotPresent;
|
||||
BOOLEAN ReportedMissing;
|
||||
BOOLEAN ExpectedWritebackFailure;
|
||||
BOOLEAN NoTouchPmeEnable;
|
||||
BOOLEAN LegacyDriver;
|
||||
BOOLEAN UpdateHardware;
|
||||
BOOLEAN MovedDevice;
|
||||
BOOLEAN DisablePowerDown;
|
||||
BOOLEAN NeedsHotPlugConfiguration;
|
||||
BOOLEAN SwitchedIDEToNativeMode;
|
||||
BOOLEAN BIOSAllowsIDESwitchToNativeMode;
|
||||
BOOLEAN IoSpaceUnderNativeIdeControl;
|
||||
BOOLEAN OnDebugPath;
|
||||
PCI_POWER_STATE PowerState;
|
||||
PCI_HEADER_TYPE_DEPENDENT Dependent;
|
||||
ULONGLONG HackFlags;
|
||||
PCI_FUNCTION_RESOURCES *Resources;
|
||||
PCI_FDO_EXTENSION *BridgeFdoExtension;
|
||||
struct _PCI_PDO_EXTENSION *NextBridge;
|
||||
struct _PCI_PDO_EXTENSION *NextHashEntry;
|
||||
PCI_LOCK Lock;
|
||||
PCI_PMC PowerCapabilities;
|
||||
BOOLEAN TargetAgpCapabilityId;
|
||||
USHORT CommandEnables;
|
||||
USHORT InitialCommand;
|
||||
} PCI_PDO_EXTENSION, *PPCI_PDO_EXTENSION;
|
||||
|
||||
//
|
||||
// IRP Dispatch Function Type
|
||||
//
|
||||
|
@ -579,6 +666,16 @@ PciGetConfigHandlers(
|
|||
IN PPCI_FDO_EXTENSION FdoExtension
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PciReadSlotConfig(
|
||||
IN PPCI_FDO_EXTENSION DeviceExtension,
|
||||
IN PCI_SLOT_NUMBER Slot,
|
||||
IN PVOID Buffer,
|
||||
IN ULONG Offset,
|
||||
IN ULONG Length
|
||||
);
|
||||
|
||||
//
|
||||
// State Machine Logic Transition Routines
|
||||
//
|
||||
|
@ -637,6 +734,12 @@ PciDebugIrpDispatchDisplay(
|
|||
IN USHORT MaxMinor
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PciDebugDumpCommonConfig(
|
||||
IN PPCI_COMMON_HEADER PciData
|
||||
);
|
||||
|
||||
//
|
||||
// Interface Support
|
||||
//
|
||||
|
@ -856,6 +959,26 @@ devpresent_Constructor(
|
|||
IN PINTERFACE Interface
|
||||
);
|
||||
|
||||
//
|
||||
// PCI Enumeration and Resources
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PciQueryDeviceRelations(
|
||||
IN PPCI_FDO_EXTENSION DeviceExtension,
|
||||
IN OUT PDEVICE_RELATIONS *pDeviceRelations
|
||||
);
|
||||
|
||||
//
|
||||
// Identification Functions
|
||||
//
|
||||
PWCHAR
|
||||
NTAPI
|
||||
PciGetDeviceDescriptionMessage(
|
||||
IN UCHAR BaseClass,
|
||||
IN UCHAR SubClass
|
||||
);
|
||||
|
||||
//
|
||||
// External Resources
|
||||
//
|
||||
|
@ -875,5 +998,7 @@ extern PCI_INTERFACE PciDevicePresentInterface;
|
|||
extern PCI_INTERFACE PciLocationInterface;
|
||||
extern PCI_INTERFACE AgpTargetInterface;
|
||||
extern PCI_INTERFACE TranslatorInterfaceInterrupt;
|
||||
extern PDRIVER_OBJECT PciDriverObject;
|
||||
extern PWATCHDOG_TABLE WdTable;
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -18,6 +18,61 @@ BOOLEAN PciAssignBusNumbers;
|
|||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PciReadWriteConfigSpace(IN PPCI_FDO_EXTENSION DeviceExtension,
|
||||
IN PCI_SLOT_NUMBER Slot,
|
||||
IN PVOID Buffer,
|
||||
IN ULONG Offset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Read)
|
||||
{
|
||||
PPCI_BUS_INTERFACE_STANDARD PciInterface;
|
||||
PBUS_HANDLER BusHandler;
|
||||
PPCIBUSDATA BusData;
|
||||
PciReadWriteConfig HalFunction;
|
||||
|
||||
/* Only the root FDO can access configuration space */
|
||||
ASSERT(PCI_IS_ROOT_FDO(DeviceExtension->BusRootFdoExtension));
|
||||
|
||||
/* Get the ACPI-compliant PCI interface */
|
||||
PciInterface = DeviceExtension->BusRootFdoExtension->PciBusInterface;
|
||||
if (PciInterface)
|
||||
{
|
||||
/* Currently this driver only supports the legacy HAL interface */
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make sure there's a registered HAL bus handler */
|
||||
ASSERT(DeviceExtension->BusHandler);
|
||||
|
||||
/* PCI Bus Number assignment is only valid on ACPI systems */
|
||||
ASSERT(!PciAssignBusNumbers);
|
||||
|
||||
/* Grab the HAL PCI Bus Handler data */
|
||||
BusHandler = (PBUS_HANDLER)DeviceExtension->BusHandler;
|
||||
BusData = (PPCIBUSDATA)BusHandler->BusData;
|
||||
|
||||
/* Choose the appropriate read or write function, and call it */
|
||||
HalFunction = Read ? BusData->ReadConfig : BusData->WriteConfig;
|
||||
HalFunction(BusHandler, Slot, Buffer, Offset, Length);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PciReadSlotConfig(IN PPCI_FDO_EXTENSION DeviceExtension,
|
||||
IN PCI_SLOT_NUMBER Slot,
|
||||
IN PVOID Buffer,
|
||||
IN ULONG Offset,
|
||||
IN ULONG Length)
|
||||
{
|
||||
/* Call the generic worker function */
|
||||
PciReadWriteConfigSpace(DeviceExtension, Slot, Buffer, Offset, Length, TRUE);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PciQueryForPciBusInterface(IN PPCI_FDO_EXTENSION FdoExtension)
|
||||
|
|
|
@ -16,4 +16,95 @@
|
|||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
PWCHAR
|
||||
NTAPI
|
||||
PciGetDescriptionMessage(IN ULONG Identifier,
|
||||
OUT PULONG Length)
|
||||
{
|
||||
PMESSAGE_RESOURCE_ENTRY Entry;
|
||||
ULONG TextLength;
|
||||
PWCHAR Description, Buffer;
|
||||
ANSI_STRING MessageString;
|
||||
UNICODE_STRING UnicodeString;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Find the message identifier in the message table */
|
||||
MessageString.Buffer = NULL;
|
||||
Status = RtlFindMessage(PciDriverObject->DriverStart,
|
||||
11, // RT_MESSAGETABLE
|
||||
LANG_NEUTRAL,
|
||||
Identifier,
|
||||
&Entry);
|
||||
if (!NT_SUCCESS(Status)) return NULL;
|
||||
|
||||
/* Check if the resource data is Unicode or ANSI */
|
||||
if (Entry->Flags & MESSAGE_RESOURCE_UNICODE)
|
||||
{
|
||||
/* Subtract one space for the end-of-message terminator */
|
||||
TextLength = Entry->Length -
|
||||
FIELD_OFFSET(MESSAGE_RESOURCE_ENTRY, Text) -
|
||||
sizeof(WCHAR);
|
||||
|
||||
/* Grab the text */
|
||||
Description = (PWCHAR)Entry->Text;
|
||||
|
||||
/* Validate valid message length, ending with a newline character */
|
||||
ASSERT(TextLength > 1);
|
||||
ASSERT(Description[TextLength / sizeof(WCHAR) == L'\n']);
|
||||
|
||||
/* Allocate the buffer to hold the message string */
|
||||
Buffer = ExAllocatePoolWithTag(PagedPool, TextLength, 'BicP');
|
||||
if (!Buffer) return NULL;
|
||||
|
||||
/* Copy the message, minus the newline character, and terminate it */
|
||||
RtlCopyMemory(Buffer, Entry->Text, TextLength - 1);
|
||||
Buffer[TextLength / sizeof(WCHAR)] = UNICODE_NULL;
|
||||
|
||||
/* Return the length to the caller */
|
||||
if (Length) *Length = UnicodeString.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialize the entry as a string */
|
||||
RtlInitAnsiString(&MessageString, (PCHAR)Entry->Text);
|
||||
|
||||
/* Remove the newline character */
|
||||
MessageString.Length -= sizeof(CHAR);
|
||||
|
||||
/* Convert it to Unicode */
|
||||
RtlAnsiStringToUnicodeString(&UnicodeString, &MessageString, TRUE);
|
||||
Buffer = UnicodeString.Buffer;
|
||||
|
||||
/* Return the length to the caller */
|
||||
if (Length) *Length = UnicodeString.Length;
|
||||
}
|
||||
|
||||
/* Return the message buffer to the caller */
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
PWCHAR
|
||||
NTAPI
|
||||
PciGetDeviceDescriptionMessage(IN UCHAR BaseClass,
|
||||
IN UCHAR SubClass)
|
||||
{
|
||||
PWCHAR Message;
|
||||
ULONG Identifier;
|
||||
|
||||
/* The message identifier in the table is encoded based on the PCI class */
|
||||
Identifier = (BaseClass << 8) | SubClass;
|
||||
|
||||
/* Go grab the description message for this device */
|
||||
Message = PciGetDescriptionMessage(Identifier, NULL);
|
||||
if (!Message)
|
||||
{
|
||||
/* It wasn't found, allocate a buffer for a generic description */
|
||||
Message = ExAllocatePoolWithTag(PagedPool, sizeof(L"PCI Device"), 'bicP');
|
||||
if (Message) RtlCopyMemory(Message, L"PCI Device", sizeof(L"PCI Device"));
|
||||
}
|
||||
|
||||
/* Return the description message */
|
||||
return Message;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue