-/* $Id$
- *
+/*
* PROJECT: ReactOS PCI bus driver
* FILE: pdo.c
* PURPOSE: Child device object dispatch routines
*/
#include <ddk/ntddk.h>
+#include <ddk/ntifs.h>
#include <initguid.h>
#include <ddk/wdmguid.h>
#include "pcidef.h"
switch (IrpSp->Parameters.QueryId.IdType) {
case BusQueryDeviceID:
- Status = PciDuplicateUnicodeString(
- &String,
+ Status = RtlDuplicateUnicodeString(
+ RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
&DeviceExtension->DeviceID,
- PagedPool);
+ &String);
DPRINT("DeviceID: %S\n", String.Buffer);
break;
case BusQueryHardwareIDs:
- Status = PciDuplicateUnicodeString(
- &String,
+ Status = RtlDuplicateUnicodeString(
+ RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
&DeviceExtension->HardwareIDs,
- PagedPool);
+ &String);
Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
break;
case BusQueryCompatibleIDs:
- Status = PciDuplicateUnicodeString(
- &String,
+ Status = RtlDuplicateUnicodeString(
+ RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
&DeviceExtension->CompatibleIDs,
- PagedPool);
+ &String);
Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
break;
case BusQueryInstanceID:
- Status = PciDuplicateUnicodeString(
- &String,
+ Status = RtlDuplicateUnicodeString(
+ RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
&DeviceExtension->InstanceID,
- PagedPool);
+ &String);
DPRINT("InstanceID: %S\n", String.Buffer);
{
BusInformation->BusTypeGuid = GUID_BUS_TYPE_PCI;
BusInformation->LegacyBusType = PCIBus;
- BusInformation->BusNumber = DeviceExtension->BusNumber;
+ BusInformation->BusNumber = DeviceExtension->PciDevice->BusNumber;
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
DeviceCapabilities->UniqueID = FALSE;
- DeviceCapabilities->Address = DeviceExtension->SlotNumber.u.AsULONG;
+ DeviceCapabilities->Address = DeviceExtension->PciDevice->SlotNumber.u.AsULONG;
DeviceCapabilities->UINumber = (ULONG)-1; /* FIXME */
return STATUS_SUCCESS;
/* Save original value */
Size= HalGetBusDataByOffset(PCIConfiguration,
- DeviceExtension->BusNumber,
- DeviceExtension->SlotNumber.u.AsULONG,
+ DeviceExtension->PciDevice->BusNumber,
+ DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
&OrigValue,
Offset,
sizeof(ULONG));
/* Set magic value */
NewValue = (ULONG)-1;
Size= HalSetBusDataByOffset(PCIConfiguration,
- DeviceExtension->BusNumber,
- DeviceExtension->SlotNumber.u.AsULONG,
+ DeviceExtension->PciDevice->BusNumber,
+ DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
&NewValue,
Offset,
sizeof(ULONG));
/* Get the range length */
Size= HalGetBusDataByOffset(PCIConfiguration,
- DeviceExtension->BusNumber,
- DeviceExtension->SlotNumber.u.AsULONG,
+ DeviceExtension->PciDevice->BusNumber,
+ DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
&NewValue,
Offset,
sizeof(ULONG));
/* Restore original value */
Size= HalSetBusDataByOffset(PCIConfiguration,
- DeviceExtension->BusNumber,
- DeviceExtension->SlotNumber.u.AsULONG,
+ DeviceExtension->PciDevice->BusNumber,
+ DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
&OrigValue,
Offset,
sizeof(ULONG));
/* Get PCI configuration space */
Size= HalGetBusData(PCIConfiguration,
- DeviceExtension->BusNumber,
- DeviceExtension->SlotNumber.u.AsULONG,
+ DeviceExtension->PciDevice->BusNumber,
+ DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
&PciConfig,
- sizeof(PCI_COMMON_CONFIG));
+ PCI_COMMON_HDR_LENGTH);
DPRINT("Size %lu\n", Size);
- if (Size < sizeof(PCI_COMMON_CONFIG))
+ if (Size < PCI_COMMON_HDR_LENGTH)
{
Irp->IoStatus.Information = 0;
return STATUS_UNSUCCESSFUL;
if (Length != 0)
ResCount += 2;
}
+ if (DeviceExtension->PciDevice->PciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV)
+ ResCount++;
}
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
{
ResourceList->ListSize = ListSize;
ResourceList->InterfaceType = PCIBus;
- ResourceList->BusNumber = DeviceExtension->BusNumber,
- ResourceList->SlotNumber = DeviceExtension->SlotNumber.u.AsULONG,
+ ResourceList->BusNumber = DeviceExtension->PciDevice->BusNumber;
+ ResourceList->SlotNumber = DeviceExtension->PciDevice->SlotNumber.u.AsULONG;
ResourceList->AlternativeLists = 1;
ResourceList->List[0].Version = 1;
ResourceList->List[0].Count = ResCount;
Descriptor = &ResourceList->List[0].Descriptors[0];
- if (PCI_CONFIGURATION_TYPE(&PciConfig) == 0)
+ if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
{
for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
{
Descriptor->u.Interrupt.MaximumVector = 0xFF;
}
}
- else if (PCI_CONFIGURATION_TYPE(&PciConfig) == 1)
+ else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
{
for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
{
}
Descriptor++;
}
+ if (DeviceExtension->PciDevice->PciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV)
+ {
+ Descriptor->Option = 0; /* Required */
+ Descriptor->Type = CmResourceTypeBusNumber;
+ Descriptor->ShareDisposition = CmResourceShareShared;
+ Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
+
+ Descriptor->u.BusNumber.MinBusNumber =
+ Descriptor->u.BusNumber.MaxBusNumber = DeviceExtension->PciDevice->PciConfig.u.type1.SubordinateBus;
+ Descriptor->u.BusNumber.Length = 1;
+ Descriptor->u.BusNumber.Reserved = 0;
+ }
}
- else if (PCI_CONFIGURATION_TYPE(&PciConfig) == 2)
+ else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
{
/* FIXME: Add Cardbus bridge resources */
}
/* Get PCI configuration space */
Size= HalGetBusData(PCIConfiguration,
- DeviceExtension->BusNumber,
- DeviceExtension->SlotNumber.u.AsULONG,
+ DeviceExtension->PciDevice->BusNumber,
+ DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
&PciConfig,
- sizeof(PCI_COMMON_CONFIG));
+ PCI_COMMON_HDR_LENGTH);
DPRINT("Size %lu\n", Size);
- if (Size < sizeof(PCI_COMMON_CONFIG))
+ if (Size < PCI_COMMON_HDR_LENGTH)
{
Irp->IoStatus.Information = 0;
return STATUS_UNSUCCESSFUL;
/* Count required resource descriptors */
ResCount = 0;
- if (PCI_CONFIGURATION_TYPE(&PciConfig) == 0)
+ if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
{
for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
{
(PciConfig.u.type0.InterruptLine != 0xFF))
ResCount++;
}
- else if (PCI_CONFIGURATION_TYPE(&PciConfig) == 1)
+ else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
{
for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
{
ResCount++;
}
}
- else if (PCI_CONFIGURATION_TYPE(&PciConfig) == 2)
+ else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
{
}
ResourceList->Count = 1;
ResourceList->List[0].InterfaceType = PCIConfiguration;
- ResourceList->List[0].BusNumber = DeviceExtension->BusNumber;
+ ResourceList->List[0].BusNumber = DeviceExtension->PciDevice->BusNumber;
PartialList = &ResourceList->List[0].PartialResourceList;
PartialList->Version = 0;
PartialList->Count = ResCount;
Descriptor = &PartialList->PartialDescriptors[0];
- if (PCI_CONFIGURATION_TYPE(&PciConfig) == 0)
+ if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
{
for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
{
Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
}
}
- else if (PCI_CONFIGURATION_TYPE(&PciConfig) == 1)
+ else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
{
for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
{
Descriptor++;
}
}
- else if (PCI_CONFIGURATION_TYPE(&PciConfig) == 2)
+ else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
{
/* FIXME: Cardbus */
}
}
+static VOID NTAPI
+InterfaceReference(
+ IN PVOID Context)
+{
+ PPDO_DEVICE_EXTENSION DeviceExtension;
+
+ DPRINT("InterfaceReference(%p)\n", Context);
+
+ DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
+ InterlockedIncrement(&DeviceExtension->References);
+}
+
+
+static VOID NTAPI
+InterfaceDereference(
+ IN PVOID Context)
+{
+ PPDO_DEVICE_EXTENSION DeviceExtension;
+
+ DPRINT("InterfaceDereference(%p)\n", Context);
+
+ DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
+ InterlockedDecrement(&DeviceExtension->References);
+}
+
+
+static BOOLEAN NTAPI
+InterfaceBusTranslateBusAddress(
+ IN PVOID Context,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN ULONG Length,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ PPDO_DEVICE_EXTENSION DeviceExtension;
+ PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+
+ DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
+ Context, BusAddress, Length, AddressSpace, TranslatedAddress);
+
+ DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
+ FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->Fdo->DeviceExtension;
+
+ return HalTranslateBusAddress(
+ PCIBus, FdoDeviceExtension->BusNumber,
+ BusAddress, AddressSpace, TranslatedAddress);
+}
+
+
+static PDMA_ADAPTER NTAPI
+InterfaceBusGetDmaAdapter(
+ IN PVOID Context,
+ IN PDEVICE_DESCRIPTION DeviceDescription,
+ OUT PULONG NumberOfMapRegisters)
+{
+ DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
+ Context, DeviceDescription, NumberOfMapRegisters);
+ return (PDMA_ADAPTER)HalGetAdapter(DeviceDescription, NumberOfMapRegisters);
+}
+
+
+static ULONG NTAPI
+InterfaceBusSetBusData(
+ IN PVOID Context,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length)
+{
+ PPDO_DEVICE_EXTENSION DeviceExtension;
+ ULONG Size;
+
+ DPRINT("InterfaceBusSetBusData()\n",
+ Context, DataType, Buffer, Offset, Length);
+
+ if (DataType != PCI_WHICHSPACE_CONFIG)
+ {
+ DPRINT("Unknown DataType %lu\n", DataType);
+ return 0;
+ }
+
+ DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
+
+ /* Get PCI configuration space */
+ Size = HalSetBusDataByOffset(PCIConfiguration,
+ DeviceExtension->PciDevice->BusNumber,
+ DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+ Buffer,
+ Offset,
+ Length);
+ return Size;
+}
+
+
+static ULONG NTAPI
+InterfaceBusGetBusData(
+ IN PVOID Context,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length)
+{
+ PPDO_DEVICE_EXTENSION DeviceExtension;
+ ULONG Size;
+
+ DPRINT("InterfaceBusGetBusData() called\n",
+ Context, DataType, Buffer, Offset, Length);
+
+ if (DataType != PCI_WHICHSPACE_CONFIG)
+ {
+ DPRINT("Unknown DataType %lu\n", DataType);
+ return 0;
+ }
+
+ DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
+
+ /* Get PCI configuration space */
+ Size = HalGetBusDataByOffset(PCIConfiguration,
+ DeviceExtension->PciDevice->BusNumber,
+ DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+ Buffer,
+ Offset,
+ Length);
+ return Size;
+}
+
+
+static NTSTATUS
+PdoQueryInterface(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+{
+ NTSTATUS Status;
+
+ if (RtlCompareMemory(IrpSp->Parameters.QueryInterface.InterfaceType,
+ &GUID_BUS_INTERFACE_STANDARD, sizeof(GUID)) == sizeof(GUID))
+ {
+ /* BUS_INTERFACE STANDARD */
+ if (IrpSp->Parameters.QueryInterface.Version < 1)
+ Status = STATUS_NOT_SUPPORTED;
+ else if (IrpSp->Parameters.QueryInterface.Size < sizeof(BUS_INTERFACE_STANDARD))
+ Status = STATUS_BUFFER_TOO_SMALL;
+ else
+ {
+ PBUS_INTERFACE_STANDARD BusInterface;
+ BusInterface = (PBUS_INTERFACE_STANDARD)IrpSp->Parameters.QueryInterface.Interface;
+ BusInterface->Size = sizeof(BUS_INTERFACE_STANDARD);
+ BusInterface->Version = 1;
+ BusInterface->Context = DeviceObject;
+ BusInterface->InterfaceReference = InterfaceReference;
+ BusInterface->InterfaceDereference = InterfaceDereference;
+ BusInterface->TranslateBusAddress = InterfaceBusTranslateBusAddress;
+ BusInterface->GetDmaAdapter = InterfaceBusGetDmaAdapter;
+ BusInterface->SetBusData = InterfaceBusSetBusData;
+ BusInterface->GetBusData = InterfaceBusGetBusData;
+ Status = STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ /* Not a supported interface */
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ /* Add a reference for the returned interface */
+ PINTERFACE Interface;
+ Interface = (PINTERFACE)IrpSp->Parameters.QueryInterface.Interface;
+ Interface->InterfaceReference(Interface->Context);
+ }
+
+ return Status;
+}
+
+
static NTSTATUS
PdoReadConfig(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
- PPDO_DEVICE_EXTENSION DeviceExtension;
ULONG Size;
- DPRINT1("PdoReadConfig() called\n");
-
- DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ DPRINT("PdoReadConfig() called\n");
-#if 0
- if (IrpSp->Parameters.ReadWriteConfig.WhichSpace != PCI_WHICHSPACE_CONFIG)
- return STATUS_NOT_SUPPORTED;
-#endif
+ Size = InterfaceBusGetBusData(
+ DeviceObject,
+ IrpSp->Parameters.ReadWriteConfig.WhichSpace,
+ IrpSp->Parameters.ReadWriteConfig.Buffer,
+ IrpSp->Parameters.ReadWriteConfig.Offset,
+ IrpSp->Parameters.ReadWriteConfig.Length);
- /* Get PCI configuration space */
- Size= HalGetBusDataByOffset(PCIConfiguration,
- DeviceExtension->BusNumber,
- DeviceExtension->SlotNumber.u.AsULONG,
- IrpSp->Parameters.ReadWriteConfig.Buffer,
- IrpSp->Parameters.ReadWriteConfig.Offset,
- IrpSp->Parameters.ReadWriteConfig.Length);
if (Size != IrpSp->Parameters.ReadWriteConfig.Length)
{
DPRINT1("Size %lu Length %lu\n", Size, IrpSp->Parameters.ReadWriteConfig.Length);
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
- PPDO_DEVICE_EXTENSION DeviceExtension;
ULONG Size;
DPRINT1("PdoWriteConfig() called\n");
- DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-#if 0
- if (IrpSp->Parameters.ReadWriteConfig.WhichSpace != PCI_WHICHSPACE_CONFIG)
- return STATUS_NOT_SUPPORTED;
-#endif
-
/* Get PCI configuration space */
- Size= HalSetBusDataByOffset(PCIConfiguration,
- DeviceExtension->BusNumber,
- DeviceExtension->SlotNumber.u.AsULONG,
- IrpSp->Parameters.ReadWriteConfig.Buffer,
- IrpSp->Parameters.ReadWriteConfig.Offset,
- IrpSp->Parameters.ReadWriteConfig.Length);
+ Size = InterfaceBusSetBusData(
+ DeviceObject,
+ IrpSp->Parameters.ReadWriteConfig.WhichSpace,
+ IrpSp->Parameters.ReadWriteConfig.Buffer,
+ IrpSp->Parameters.ReadWriteConfig.Offset,
+ IrpSp->Parameters.ReadWriteConfig.Length);
+
if (Size != IrpSp->Parameters.ReadWriteConfig.Length)
{
DPRINT1("Size %lu Length %lu\n", Size, IrpSp->Parameters.ReadWriteConfig.Length);
Status = STATUS_SUCCESS;
break;
+ case IRP_MN_QUERY_INTERFACE:
+ DPRINT("IRP_MN_QUERY_INTERFACE received\n");
+ Status = PdoQueryInterface(DeviceObject, Irp, IrpSp);
+ break;
+
case IRP_MN_READ_CONFIG:
- DPRINT1("IRP_MN_READ_CONFIG received\n");
+ DPRINT("IRP_MN_READ_CONFIG received\n");
Status = PdoReadConfig(DeviceObject, Irp, IrpSp);
break;
case IRP_MN_WRITE_CONFIG:
- DPRINT1("IRP_MN_WRITE_CONFIG received\n");
+ DPRINT("IRP_MN_WRITE_CONFIG received\n");
Status = PdoWriteConfig(DeviceObject, Irp, IrpSp);
break;
default:
- DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
+ DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction);
break;
}