Implement:
authorEric Kohl <eric.kohl@reactos.org>
Mon, 16 Aug 2004 09:13:00 +0000 (09:13 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 16 Aug 2004 09:13:00 +0000 (09:13 +0000)
  - IRP_MN_READ_CONFIG
  - IRP_MN_WRITE_CONFIG
  - IRP_MN_QUERY_RESOURCES
  - IRP_MN_QUREY_DEVICE_TEXT

Implement (disabled):
  - IRP_MN_QUERY_ID.BusQueryInstanceID

svn path=/trunk/; revision=10570

reactos/drivers/bus/pci/fdo.c
reactos/drivers/bus/pci/pci.c
reactos/drivers/bus/pci/pci.h
reactos/drivers/bus/pci/pdo.c

index 29eba5f..9e8b6f5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fdo.c,v 1.8 2004/06/09 14:22:53 ekohl Exp $
+/* $Id: fdo.c,v 1.9 2004/08/16 09:13:00 ekohl Exp $
  *
  * PROJECT:         ReactOS PCI bus driver
  * FILE:            fdo.c
@@ -93,11 +93,19 @@ FdoEnumerateDevices(
       {
         SlotNumber.u.bits.FunctionNumber = FunctionNumber;
 
-        Size= HalGetBusData(PCIConfiguration,
-                            BusNumber,
-                            SlotNumber.u.AsULONG,
-                            &PciConfig,
-                            sizeof(PCI_COMMON_CONFIG));
+        DPRINT("Bus %1lu  Device %2lu  Func %1lu\n",
+          BusNumber,
+          DeviceNumber,
+          FunctionNumber);
+
+        RtlZeroMemory(&PciConfig,
+                      sizeof(PCI_COMMON_CONFIG));
+
+        Size = HalGetBusData(PCIConfiguration,
+                             BusNumber,
+                             SlotNumber.u.AsULONG,
+                             &PciConfig,
+                             sizeof(PCI_COMMON_CONFIG));
         DPRINT("Size %lu\n", Size);
         if (Size < sizeof(PCI_COMMON_CONFIG))
         {
@@ -151,6 +159,13 @@ FdoEnumerateDevices(
         Device->RemovePending = FALSE;
 
         DeviceExtension->DeviceListCount++;
+
+        /* Skip to next device if the current one is not a multifunction device */
+        if ((FunctionNumber == 0) &&
+            ((PciConfig.HeaderType & 0x80) == 0))
+        {
+          break;
+        }
       }
     }
   }
@@ -290,6 +305,24 @@ FdoQueryBusRelations(
         ErrorOccurred = TRUE;
         break;
       }
+
+      /* Add device description string */
+      if (!PciCreateDeviceDescriptionString(&PdoDeviceExtension->DeviceDescription,
+                                            Device))
+      {
+        ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
+        ErrorOccurred = TRUE;
+        break;
+      }
+
+      /* Add device location string */
+      if (!PciCreateDeviceLocationString(&PdoDeviceExtension->DeviceLocation,
+                                         Device))
+      {
+        ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
+        ErrorOccurred = TRUE;
+        break;
+      }
     }
 
     if (!Device->RemovePending) {
@@ -449,7 +482,7 @@ FdoPnpControl(
     break;
 #endif
   default:
-    DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);\r\r
+    DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
 
     /*
      * Do NOT complete the IRP as it will be processed by the lower
index ce7a1b3..d00012d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.7 2004/06/09 14:22:53 ekohl Exp $
+/* $Id: pci.c,v 1.8 2004/08/16 09:13:00 ekohl Exp $
  *
  * PROJECT:         ReactOS PCI Bus driver
  * FILE:            pci.c
@@ -266,19 +266,36 @@ PciCreateDeviceIDString(PUNICODE_STRING DeviceID,
 
 
 BOOLEAN
-PciCreateInstanceIDString(PUNICODE_STRING DeviceID,
+PciCreateInstanceIDString(PUNICODE_STRING InstanceID,
                           PPCI_DEVICE Device)
 {
-  /* FIXME */
-
 #if 0
-  swprintf(Buffer,
-           L"%02lx&%04lx",
-           Device->BusNumber,
-           Device->SlotNumber.SlotNumber.u.AsULONG);
-#endif
+  WCHAR Buffer[32];
+  ULONG Length;
+  ULONG Index;
+
+  Index = swprintf(Buffer,
+                   L"%lX&%02lX",
+                   Device->BusNumber,
+                   (Device->SlotNumber.u.bits.DeviceNumber << 3) +
+                   Device->SlotNumber.u.bits.FunctionNumber);
+  Index++;
+  Buffer[Index] = UNICODE_NULL;
 
-  return PciCreateUnicodeString(DeviceID, L"0000", PagedPool);
+  Length = (Index + 1) * sizeof(WCHAR);
+  InstanceID->Buffer = ExAllocatePool(PagedPool, Length);
+  if (InstanceID->Buffer == NULL)
+  {
+    return FALSE;
+  }
+
+  InstanceID->Length = Length - sizeof(WCHAR);
+  InstanceID->MaximumLength = Length;
+  RtlCopyMemory(InstanceID->Buffer, Buffer, Length);
+
+  return TRUE;
+#endif
+  return PciCreateUnicodeString(InstanceID, L"0000", PagedPool);
 }
 
 
@@ -312,7 +329,7 @@ PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs,
 
   Length = (Index + 1) * sizeof(WCHAR);
   HardwareIDs->Buffer = ExAllocatePool(PagedPool, Length);
-  if (Buffer == NULL)
+  if (HardwareIDs->Buffer == NULL)
   {
     return FALSE;
   }
@@ -326,7 +343,7 @@ PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs,
 
 
 BOOLEAN
-PciCreateCompatibleIDsString(PUNICODE_STRING HardwareIDs,
+PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs,
                              PPCI_DEVICE Device)
 {
   WCHAR Buffer[256];
@@ -396,15 +413,113 @@ PciCreateCompatibleIDsString(PUNICODE_STRING HardwareIDs,
   Buffer[Index] = UNICODE_NULL;
 
   Length = (Index + 1) * sizeof(WCHAR);
-  HardwareIDs->Buffer = ExAllocatePool(PagedPool, Length);
-  if (Buffer == NULL)
+  CompatibleIDs->Buffer = ExAllocatePool(PagedPool, Length);
+  if (CompatibleIDs->Buffer == NULL)
   {
     return FALSE;
   }
 
-  HardwareIDs->Length = Length - sizeof(WCHAR);
-  HardwareIDs->MaximumLength = Length;
-  RtlCopyMemory(HardwareIDs->Buffer, Buffer, Length);
+  CompatibleIDs->Length = Length - sizeof(WCHAR);
+  CompatibleIDs->MaximumLength = Length;
+  RtlCopyMemory(CompatibleIDs->Buffer, Buffer, Length);
+
+  return TRUE;
+}
+
+
+BOOLEAN
+PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription,
+                                 PPCI_DEVICE Device)
+{
+  PWSTR Description;
+  ULONG Length;
+
+  switch (Device->PciConfig.BaseClass)
+  {
+    case PCI_CLASS_MASS_STORAGE_CTLR:
+      switch (Device->PciConfig.BaseClass)
+      {
+        case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR:
+          Description = L"SCSI controller";
+          break;
+
+        case PCI_SUBCLASS_MSC_IDE_CTLR:
+          Description = L"IDE controller";
+          break;
+
+        case PCI_SUBCLASS_MSC_FLOPPY_CTLR:
+          Description = L"Floppy disk controller";
+          break;
+
+        case PCI_SUBCLASS_MSC_IPI_CTLR:
+          Description = L"IPI controller";
+          break;
+
+        case PCI_SUBCLASS_MSC_RAID_CTLR:
+          Description = L"RAID controller";
+          break;
+
+        default:
+          Description = L"Mass storage controller";
+      }
+      break;
+
+    case PCI_CLASS_NETWORK_CTLR:
+      switch (Device->PciConfig.BaseClass)
+      {
+
+        default:
+          Description = L"Network controller";
+      }
+      break;
+
+    default:
+      Description = L"PCI-Device";
+  }
+
+  Length = (wcslen(Description) + 1) * sizeof(WCHAR);
+  DeviceDescription->Buffer = ExAllocatePool(PagedPool, Length);
+  if (DeviceDescription->Buffer == NULL)
+  {
+    return FALSE;
+  }
+
+  DeviceDescription->Length = Length - sizeof(WCHAR);
+  DeviceDescription->MaximumLength = Length;
+  RtlCopyMemory(DeviceDescription->Buffer, Description, Length);
+
+  return TRUE;
+}
+
+
+BOOLEAN
+PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation,
+                              PPCI_DEVICE Device)
+{
+  WCHAR Buffer[256];
+  ULONG Length;
+  ULONG Index;
+
+  Index = 0;
+  Index += swprintf(&Buffer[Index],
+                    L"PCI-Bus %lu, Device %u, Function %u",
+                    Device->BusNumber,
+                    Device->SlotNumber.u.bits.DeviceNumber,
+                    Device->SlotNumber.u.bits.FunctionNumber);
+  Index++;
+
+  Buffer[Index] = UNICODE_NULL;
+
+  Length = (Index + 1) * sizeof(WCHAR);
+  DeviceLocation->Buffer = ExAllocatePool(PagedPool, Length);
+  if (DeviceLocation->Buffer == NULL)
+  {
+    return FALSE;
+  }
+
+  DeviceLocation->Length = Length - sizeof(WCHAR);
+  DeviceLocation->MaximumLength = Length;
+  RtlCopyMemory(DeviceLocation->Buffer, Buffer, Length);
 
   return TRUE;
 }
index 37f187a..bab065e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pci.h,v 1.7 2004/06/09 14:22:53 ekohl Exp $ */
+/* $Id: pci.h,v 1.8 2004/08/16 09:13:00 ekohl Exp $ */
 
 #ifndef __PCI_H
 #define __PCI_H
@@ -69,9 +69,9 @@ typedef struct _PDO_DEVICE_EXTENSION
   // Compatible IDs
   UNICODE_STRING CompatibleIDs;
   // Textual description of device
-  UNICODE_STRING DeviceText;
-  // Textual description of device
-  UNICODE_STRING DeviceTextLocation;
+  UNICODE_STRING DeviceDescription;
+  // Textual description of device location
+  UNICODE_STRING DeviceLocation;
 } __attribute((packed)) PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
 
 /* Functional Device Object device extension for the PCI driver device object */
@@ -138,6 +138,16 @@ PciCreateCompatibleIDsString(
   PUNICODE_STRING HardwareIDs,
   PPCI_DEVICE Device);
 
+BOOLEAN
+PciCreateDeviceDescriptionString(
+  PUNICODE_STRING DeviceDescription,
+  PPCI_DEVICE Device);
+
+BOOLEAN
+PciCreateDeviceLocationString(
+  PUNICODE_STRING DeviceLocation,
+  PPCI_DEVICE Device);
+
 /* pdo.c */
 
 NTSTATUS
index a1454e3..05f47a5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pdo.c,v 1.5 2004/06/09 14:22:53 ekohl Exp $
+/* $Id: pdo.c,v 1.6 2004/08/16 09:13:00 ekohl Exp $
  *
  * PROJECT:         ReactOS PCI bus driver
  * FILE:            pdo.c
@@ -20,7 +20,43 @@ DEFINE_GUID(GUID_BUS_TYPE_PCI, 0xc8ebdfb0L, 0xb510, 0x11d0, 0x80, 0xe5, 0x00, 0x
 
 /*** PRIVATE *****************************************************************/
 
-NTSTATUS
+static NTSTATUS
+PdoQueryDeviceText(
+  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;
+
+  Status = STATUS_SUCCESS;
+
+  switch (IrpSp->Parameters.QueryDeviceText.DeviceTextType)
+  {
+    case DeviceTextDescription:
+      DPRINT("DeviceTextDescription\n");
+      Irp->IoStatus.Information = (ULONG_PTR)DeviceExtension->DeviceLocation.Buffer;
+      break;
+
+    case DeviceTextLocationInformation:
+      DPRINT("DeviceTextLocationInformation\n");
+      Irp->IoStatus.Information = (ULONG_PTR)DeviceExtension->DeviceLocation.Buffer;
+      break;
+
+    default:
+      Irp->IoStatus.Information = 0;
+      Status = STATUS_INVALID_PARAMETER;
+  }
+
+  return Status;
+}
+
+
+static NTSTATUS
 PdoQueryId(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp,
@@ -90,7 +126,7 @@ PdoQueryId(
 }
 
 
-NTSTATUS
+static NTSTATUS
 PdoQueryBusInformation(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp,
@@ -119,7 +155,7 @@ PdoQueryBusInformation(
 }
 
 
-NTSTATUS
+static NTSTATUS
 PdoQueryCapabilities(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp,
@@ -133,6 +169,8 @@ PdoQueryCapabilities(
   DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
   DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
 
+  DeviceCapabilities->UniqueID = TRUE;
+
   DeviceCapabilities->Address =
   DeviceCapabilities->UINumber = DeviceExtension->SlotNumber.u.AsULONG;
 
@@ -140,7 +178,388 @@ PdoQueryCapabilities(
 }
 
 
-NTSTATUS
+static BOOLEAN
+PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension,
+                  ULONG Offset,
+                  PULONG Base,
+                  PULONG Length,
+                  PULONG Flags)
+{
+  ULONG OrigValue;
+  ULONG BaseValue;
+  ULONG NewValue;
+  ULONG Size;
+  ULONG XLength;
+
+  /* Save original value */
+  Size= HalGetBusDataByOffset(PCIConfiguration,
+                              DeviceExtension->BusNumber,
+                              DeviceExtension->SlotNumber.u.AsULONG,
+                              &OrigValue,
+                              Offset,
+                              sizeof(ULONG));
+  if (Size != sizeof(ULONG))
+  {
+    DPRINT1("Wrong size %lu\n", Size);
+    return FALSE;
+  }
+
+  BaseValue = (OrigValue & 0x00000001) ? (OrigValue & ~0x3) : (OrigValue & ~0xF);
+
+  *Base = BaseValue;
+
+  /* Set magic value */
+  NewValue = (ULONG)-1;
+  Size= HalSetBusDataByOffset(PCIConfiguration,
+                              DeviceExtension->BusNumber,
+                              DeviceExtension->SlotNumber.u.AsULONG,
+                              &NewValue,
+                              Offset,
+                              sizeof(ULONG));
+  if (Size != sizeof(ULONG))
+  {
+    DPRINT1("Wrong size %lu\n", Size);
+    return FALSE;
+  }
+
+  /* Get the range length */
+  Size= HalGetBusDataByOffset(PCIConfiguration,
+                              DeviceExtension->BusNumber,
+                              DeviceExtension->SlotNumber.u.AsULONG,
+                              &NewValue,
+                              Offset,
+                              sizeof(ULONG));
+  if (Size != sizeof(ULONG))
+  {
+    DPRINT1("Wrong size %lu\n", Size);
+    return FALSE;
+  }
+
+  /* Restore original value */
+  Size= HalSetBusDataByOffset(PCIConfiguration,
+                              DeviceExtension->BusNumber,
+                              DeviceExtension->SlotNumber.u.AsULONG,
+                              &OrigValue,
+                              Offset,
+                              sizeof(ULONG));
+  if (Size != sizeof(ULONG))
+  {
+    DPRINT1("Wrong size %lu\n", Size);
+    return FALSE;
+  }
+
+  if (NewValue == 0)
+  {
+    DPRINT("Unused address register\n");
+    *Base = 0;
+    *Length = 0;
+    *Flags = 0;
+     return TRUE;
+  }
+
+  XLength = ~((NewValue & 0x00000001) ? (NewValue & ~0x3) : (NewValue & ~0xF)) + 1;
+
+#if 0
+  DbgPrint("BaseAddress 0x%08lx  Length 0x%08lx",
+           BaseValue, XLength);
+#endif
+
+  if (NewValue & 0x00000001)
+  {
+#if 0
+    DbgPrint("  IO range");
+#endif
+  }
+  else
+  {
+#if 0
+    DbgPrint("  Memory range");
+#endif
+    if ((NewValue & 0x00000006) == 0)
+    {
+#if 0
+      DbgPrint(" in 32-Bit address space");
+#endif
+    }
+    else if ((NewValue & 0x00000006) == 2)
+    {
+#if 0
+      DbgPrint("below 1BM ");
+#endif
+    }
+    else if ((NewValue & 0x00000006) == 4)
+    {
+#if 0
+      DbgPrint(" in 64-Bit address space");
+#endif
+    }
+
+    if (NewValue & 0x00000008)
+    {
+#if 0
+      DbgPrint(" prefetchable");
+#endif
+    }
+  }
+
+  DbgPrint("\n");
+
+  *Length = XLength;
+  *Flags = (NewValue & 0x00000001) ? (NewValue & 0x3) : (NewValue & 0xF);
+
+  return TRUE;
+}
+
+
+static NTSTATUS
+PdoQueryResourceRequirements(
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PIRP Irp,
+  PIO_STACK_LOCATION IrpSp)
+{
+  DPRINT("PdoQueryResourceRequirements() called\n");
+
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+
+static NTSTATUS
+PdoQueryResources(
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PIRP Irp,
+  PIO_STACK_LOCATION IrpSp)
+{
+  PPDO_DEVICE_EXTENSION DeviceExtension;
+  PCI_COMMON_CONFIG PciConfig;
+  PCM_RESOURCE_LIST ResourceList;
+  PCM_PARTIAL_RESOURCE_LIST PartialList;
+  PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
+  ULONG Size;
+  ULONG ResCount;
+  ULONG ListSize;
+  ULONG i;
+  ULONG Base;
+  ULONG Length;
+  ULONG Flags;
+
+  DPRINT("PdoQueryResources() called\n");
+
+  DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+  /* Get PCI configuration space */
+  Size= HalGetBusData(PCIConfiguration,
+                      DeviceExtension->BusNumber,
+                      DeviceExtension->SlotNumber.u.AsULONG,
+                      &PciConfig,
+                      sizeof(PCI_COMMON_CONFIG));
+  DPRINT("Size %lu\n", Size);
+  if (Size < sizeof(PCI_COMMON_CONFIG))
+  {
+    Irp->IoStatus.Information = 0;
+    return STATUS_UNSUCCESSFUL;
+  }
+
+  DPRINT("Command register: 0x%04hx\n", PciConfig.Command);
+
+  /* Count required resource descriptors */
+  ResCount = 0;
+  if ((PciConfig.HeaderType & 0x7F) == 0)
+  {
+    for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
+    {
+      if (PciConfig.u.type0.BaseAddresses[i] == 0)
+        break;
+
+      ResCount++;
+    }
+
+    if (PciConfig.u.type0.InterruptLine != 0xFF)
+      ResCount++;
+  }
+  else if ((PciConfig.HeaderType & 0x7F) == 1)
+  {
+    for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
+    {
+      if (PciConfig.u.type0.BaseAddresses[i] != 0)
+        break;
+
+      ResCount++;
+    }
+  }
+  else
+  {
+    DPRINT1("Unsupported header type %u\n", PciConfig.HeaderType);
+  }
+
+  /* Calculate the resource list size */
+  ListSize = sizeof(CM_RESOURCE_LIST);
+  if (ResCount > 1)
+  {
+    ListSize += ((ResCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
+  }
+
+  /* Allocate the resource list */
+  ResourceList = ExAllocatePool(PagedPool,
+                                ListSize);
+  if (ResourceList == NULL)
+    return STATUS_INSUFFICIENT_RESOURCES;
+
+  ResourceList->Count = 1;
+  ResourceList->List[0].InterfaceType = PCIConfiguration;
+  ResourceList->List[0].BusNumber = DeviceExtension->BusNumber;
+
+  PartialList = &ResourceList->List[0].PartialResourceList;
+  PartialList->Version = 0;
+  PartialList->Revision = 0;
+  PartialList->Count = ResCount;
+
+  Descriptor = &PartialList->PartialDescriptors[0];
+  if ((PciConfig.HeaderType & 0x7F) == 0)
+  {
+    for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
+    {
+      if (!PdoGetRangeLength(DeviceExtension,
+                            0x10 + i * 4,
+                            &Base,
+                            &Length,
+                            &Flags))
+      {
+        DPRINT1("PdoGetRangeLength() failed\n");
+        break;
+      }
+
+      if (Length == 0)
+      {
+        DPRINT("Unused address register\n");
+        break;
+      }
+
+      if (Flags & PCI_ADDRESS_IO_SPACE)
+      {
+        Descriptor->Type = CmResourceTypePort;
+//        Descriptor->ShareDisposition =
+        Descriptor->Flags = CM_RESOURCE_PORT_IO;
+        Descriptor->u.Port.Start.QuadPart =
+          (ULONGLONG)Base;
+        Descriptor->u.Port.Length = Length;
+      }
+      else
+      {
+        Descriptor->Type = CmResourceTypeMemory;
+//        Descriptor->ShareDisposition =
+        Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+        Descriptor->u.Memory.Start.QuadPart =
+          (ULONGLONG)Base;
+        Descriptor->u.Memory.Length = Length;
+      }
+
+      Descriptor++;
+    }
+
+    if (PciConfig.u.type0.InterruptLine != 0xFF)
+    {
+      Descriptor->Type = CmResourceTypeInterrupt;
+//      Descriptor->ShareDisposition =
+      Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
+      Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine;
+      Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine;
+      Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+    }
+  }
+#if 0
+  else if ((PciConfig.HeaderType & 0x7F) == 1)
+  {
+    for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
+    {
+      if (PciConfig.u.type0.BaseAddresses[i] != 0)
+        ResCount++;
+    }
+  }
+#endif
+
+  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+
+  return STATUS_SUCCESS;
+}
+
+
+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;
+
+#if 0
+  if (IrpSp->Parameters.ReadWriteConfig.WhichSpace != PCI_WHICHSPACE_CONFIG)
+    return STATUS_NOT_SUPPORTED;
+#endif
+
+  /* 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);
+    Irp->IoStatus.Information = 0;
+    return STATUS_UNSUCCESSFUL;
+  }
+
+  Irp->IoStatus.Information = Size;
+
+  return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+PdoWriteConfig(
+  IN PDEVICE_OBJECT DeviceObject,
+  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);
+  if (Size != IrpSp->Parameters.ReadWriteConfig.Length)
+  {
+    DPRINT1("Size %lu  Length %lu\n", Size, IrpSp->Parameters.ReadWriteConfig.Length);
+    Irp->IoStatus.Information = 0;
+    return STATUS_UNSUCCESSFUL;
+  }
+
+  Irp->IoStatus.Information = Size;
+
+  return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
 PdoSetPower(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp,
@@ -218,12 +637,15 @@ PdoPnpControl(
   case IRP_MN_QUERY_DEVICE_RELATIONS:
     /* FIXME: Possibly handle for RemovalRelations */
     break;
+#endif
 
   case IRP_MN_QUERY_DEVICE_TEXT:
+    DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
+    Status = PdoQueryDeviceText(DeviceObject, Irp, IrpSp);
     break;
-#endif
 
   case IRP_MN_QUERY_ID:
+    DPRINT("IRP_MN_QUERY_ID received\n");
     Status = PdoQueryId(DeviceObject, Irp, IrpSp);
     break;
 
@@ -233,13 +655,19 @@ PdoPnpControl(
 
   case IRP_MN_QUERY_REMOVE_DEVICE:
     break;
+#endif
 
   case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
+    DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
+    Status = PdoQueryResourceRequirements(DeviceObject, Irp, IrpSp);
     break;
 
   case IRP_MN_QUERY_RESOURCES:
+    DPRINT("IRP_MN_QUERY_RESOURCES received\n");
+    Status = PdoQueryResources(DeviceObject, Irp, IrpSp);
     break;
 
+#if 0
   case IRP_MN_QUERY_STOP_DEVICE:
     break;
 
@@ -258,6 +686,17 @@ PdoPnpControl(
   case IRP_MN_SURPRISE_REMOVAL:
     break;
 #endif
+
+  case IRP_MN_READ_CONFIG:
+    DPRINT1("IRP_MN_READ_CONFIG received\n");
+    Status = PdoReadConfig(DeviceObject, Irp, IrpSp);
+    break;
+
+  case IRP_MN_WRITE_CONFIG:
+    DPRINT1("IRP_MN_WRITE_CONFIG received\n");
+    Status = PdoWriteConfig(DeviceObject, Irp, IrpSp);
+    break;
+
   default:
     DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
     break;