- Assign a proper InterfaceType to the resource descriptor. Fixes assert when using...
[reactos.git] / reactos / drivers / bus / pci / pdo.c
index 05f47a5..1f04bb8 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: pdo.c,v 1.6 2004/08/16 09:13:00 ekohl Exp $
- *
+/*
  * PROJECT:         ReactOS PCI bus driver
  * FILE:            pdo.c
  * PURPOSE:         Child device object dispatch routines
@@ -8,16 +7,11 @@
  *      10-09-2001  CSH  Created
  */
 
-#include <ddk/ntddk.h>
-
-#include "pcidef.h"
 #include "pci.h"
 
 #define NDEBUG
 #include <debug.h>
 
-DEFINE_GUID(GUID_BUS_TYPE_PCI, 0xc8ebdfb0L, 0xb510, 0x11d0, 0x80, 0xe5, 0x00, 0xa0, 0xc9, 0x25, 0x42, 0xe3);
-
 /*** PRIVATE *****************************************************************/
 
 static NTSTATUS
@@ -39,7 +33,7 @@ PdoQueryDeviceText(
   {
     case DeviceTextDescription:
       DPRINT("DeviceTextDescription\n");
-      Irp->IoStatus.Information = (ULONG_PTR)DeviceExtension->DeviceLocation.Buffer;
+      Irp->IoStatus.Information = (ULONG_PTR)DeviceExtension->DeviceDescription.Buffer;
       break;
 
     case DeviceTextLocationInformation:
@@ -78,10 +72,10 @@ PdoQueryId(
 
   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);
 
@@ -89,28 +83,28 @@ PdoQueryId(
       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);
 
@@ -146,7 +140,7 @@ PdoQueryBusInformation(
   {
     BusInformation->BusTypeGuid = GUID_BUS_TYPE_PCI;
     BusInformation->LegacyBusType = PCIBus;
-    BusInformation->BusNumber = DeviceExtension->BusNumber;
+    BusInformation->BusNumber = DeviceExtension->PciDevice->BusNumber;
 
     return STATUS_SUCCESS;
   }
@@ -169,10 +163,12 @@ PdoQueryCapabilities(
   DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
   DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
 
-  DeviceCapabilities->UniqueID = TRUE;
+  if (DeviceCapabilities->Version != 1)
+    return STATUS_UNSUCCESSFUL;
 
-  DeviceCapabilities->Address =
-  DeviceCapabilities->UINumber = DeviceExtension->SlotNumber.u.AsULONG;
+  DeviceCapabilities->UniqueID = FALSE;
+  DeviceCapabilities->Address = DeviceExtension->PciDevice->SlotNumber.u.AsULONG;
+  DeviceCapabilities->UINumber = (ULONG)-1; /* FIXME */
 
   return STATUS_SUCCESS;
 }
@@ -193,8 +189,8 @@ PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension,
 
   /* Save original value */
   Size= HalGetBusDataByOffset(PCIConfiguration,
-                              DeviceExtension->BusNumber,
-                              DeviceExtension->SlotNumber.u.AsULONG,
+                              DeviceExtension->PciDevice->BusNumber,
+                              DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
                               &OrigValue,
                               Offset,
                               sizeof(ULONG));
@@ -211,8 +207,8 @@ PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension,
   /* 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));
@@ -224,8 +220,8 @@ PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension,
 
   /* 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));
@@ -237,8 +233,8 @@ PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension,
 
   /* Restore original value */
   Size= HalSetBusDataByOffset(PCIConfiguration,
-                              DeviceExtension->BusNumber,
-                              DeviceExtension->SlotNumber.u.AsULONG,
+                              DeviceExtension->PciDevice->BusNumber,
+                              DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
                               &OrigValue,
                               Offset,
                               sizeof(ULONG));
@@ -262,47 +258,35 @@ PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension,
 #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
+      DbgPrint(" below 1BM ");
     }
     else if ((NewValue & 0x00000006) == 4)
     {
-#if 0
       DbgPrint(" in 64-Bit address space");
-#endif
     }
 
     if (NewValue & 0x00000008)
     {
-#if 0
       DbgPrint(" prefetchable");
-#endif
     }
   }
 
   DbgPrint("\n");
+#endif
 
   *Length = XLength;
   *Flags = (NewValue & 0x00000001) ? (NewValue & 0x3) : (NewValue & 0xF);
@@ -317,9 +301,304 @@ PdoQueryResourceRequirements(
   IN PIRP Irp,
   PIO_STACK_LOCATION IrpSp)
 {
+  PPDO_DEVICE_EXTENSION DeviceExtension;
+  PCI_COMMON_CONFIG PciConfig;
+  PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
+  PIO_RESOURCE_DESCRIPTOR Descriptor;
+  ULONG Size;
+  ULONG ResCount = 0;
+  ULONG ListSize;
+  ULONG i;
+  ULONG Base;
+  ULONG Length;
+  ULONG Flags;
+
   DPRINT("PdoQueryResourceRequirements() called\n");
 
-  return STATUS_NOT_IMPLEMENTED;
+  DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+  /* Get PCI configuration space */
+  Size= HalGetBusData(PCIConfiguration,
+                      DeviceExtension->PciDevice->BusNumber,
+                      DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+                      &PciConfig,
+                      PCI_COMMON_HDR_LENGTH);
+  DPRINT("Size %lu\n", Size);
+  if (Size < PCI_COMMON_HDR_LENGTH)
+  {
+    Irp->IoStatus.Information = 0;
+    return STATUS_UNSUCCESSFUL;
+  }
+
+  DPRINT("Command register: 0x%04hx\n", PciConfig.Command);
+
+  /* Count required resource descriptors */
+  ResCount = 0;
+  if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
+  {
+    for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
+    {
+      if (!PdoGetRangeLength(DeviceExtension,
+                            0x10 + i * 4,
+                            &Base,
+                            &Length,
+                            &Flags))
+       break;
+
+      if (Length != 0)
+        ResCount += 2;
+    }
+
+    /* FIXME: Check ROM address */
+
+    if (PciConfig.u.type0.InterruptPin != 0)
+      ResCount++;
+  }
+  else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
+  {
+    for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
+    {
+      if (!PdoGetRangeLength(DeviceExtension,
+                            0x10 + i * 4,
+                            &Base,
+                            &Length,
+                            &Flags))
+       break;
+
+      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)
+  {
+    /* FIXME: Count Cardbus bridge resources */
+  }
+  else
+  {
+    DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig));
+  }
+
+  if (ResCount == 0)
+  {
+    Irp->IoStatus.Information = 0;
+    return STATUS_SUCCESS;
+  }
+
+  /* Calculate the resource list size */
+  ListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List->Descriptors)
+    + ResCount * sizeof(IO_RESOURCE_DESCRIPTOR);
+
+  DPRINT("ListSize %lu (0x%lx)\n", ListSize, ListSize);
+
+  /* Allocate the resource requirements list */
+  ResourceList = ExAllocatePool(PagedPool,
+                                ListSize);
+  if (ResourceList == NULL)
+  {
+    Irp->IoStatus.Information = 0;
+    return STATUS_INSUFFICIENT_RESOURCES;
+  }
+
+  RtlZeroMemory(ResourceList, ListSize);
+  ResourceList->ListSize = ListSize;
+  ResourceList->InterfaceType = PCIBus;
+  ResourceList->BusNumber = DeviceExtension->PciDevice->BusNumber;
+  ResourceList->SlotNumber = DeviceExtension->PciDevice->SlotNumber.u.AsULONG;
+  ResourceList->AlternativeLists = 1;
+
+  ResourceList->List[0].Version = 1;
+  ResourceList->List[0].Revision = 1;
+  ResourceList->List[0].Count = ResCount;
+
+  Descriptor = &ResourceList->List[0].Descriptors[0];
+  if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
+  {
+    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");
+        continue;
+      }
+
+      /* Set preferred descriptor */
+      Descriptor->Option = IO_RESOURCE_PREFERRED;
+      if (Flags & PCI_ADDRESS_IO_SPACE)
+      {
+        Descriptor->Type = CmResourceTypePort;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_PORT_IO |
+                            CM_RESOURCE_PORT_16_BIT_DECODE |
+                            CM_RESOURCE_PORT_POSITIVE_DECODE;
+
+        Descriptor->u.Port.Length = Length;
+        Descriptor->u.Port.Alignment = 1;
+        Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)Base;
+        Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)(Base + Length - 1);
+      }
+      else
+      {
+        Descriptor->Type = CmResourceTypeMemory;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+
+        Descriptor->u.Memory.Length = Length;
+        Descriptor->u.Memory.Alignment = 1;
+        Descriptor->u.Memory.MinimumAddress.QuadPart = (ULONGLONG)Base;
+        Descriptor->u.Memory.MaximumAddress.QuadPart = (ULONGLONG)(Base + Length - 1);
+      }
+      Descriptor++;
+
+      /* Set alternative descriptor */
+      Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
+      if (Flags & PCI_ADDRESS_IO_SPACE)
+      {
+        Descriptor->Type = CmResourceTypePort;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_PORT_IO |
+                            CM_RESOURCE_PORT_16_BIT_DECODE |
+                            CM_RESOURCE_PORT_POSITIVE_DECODE;
+
+        Descriptor->u.Port.Length = Length;
+        Descriptor->u.Port.Alignment = Length;
+        Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
+        Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
+      }
+      else
+      {
+        Descriptor->Type = CmResourceTypeMemory;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+
+        Descriptor->u.Memory.Length = Length;
+        Descriptor->u.Memory.Alignment = Length;
+        Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
+        Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
+      }
+      Descriptor++;
+    }
+
+    /* FIXME: Check ROM address */
+
+    if (PciConfig.u.type0.InterruptPin != 0)
+    {
+      Descriptor->Option = 0; /* Required */
+      Descriptor->Type = CmResourceTypeInterrupt;
+      Descriptor->ShareDisposition = CmResourceShareShared;
+      Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
+
+      Descriptor->u.Interrupt.MinimumVector = 0;
+      Descriptor->u.Interrupt.MaximumVector = 0xFF;
+    }
+  }
+  else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
+  {
+    for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
+    {
+      if (!PdoGetRangeLength(DeviceExtension,
+                            0x10 + i * 4,
+                            &Base,
+                            &Length,
+                            &Flags))
+      {
+        DPRINT1("PdoGetRangeLength() failed\n");
+        break;
+      }
+
+      if (Length == 0)
+      {
+        DPRINT("Unused address register\n");
+        continue;
+      }
+
+      /* Set preferred descriptor */
+      Descriptor->Option = IO_RESOURCE_PREFERRED;
+      if (Flags & PCI_ADDRESS_IO_SPACE)
+      {
+        Descriptor->Type = CmResourceTypePort;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_PORT_IO |
+                            CM_RESOURCE_PORT_16_BIT_DECODE |
+                            CM_RESOURCE_PORT_POSITIVE_DECODE;
+
+        Descriptor->u.Port.Length = Length;
+        Descriptor->u.Port.Alignment = 1;
+        Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)Base;
+        Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)(Base + Length - 1);
+      }
+      else
+      {
+        Descriptor->Type = CmResourceTypeMemory;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+
+        Descriptor->u.Memory.Length = Length;
+        Descriptor->u.Memory.Alignment = 1;
+        Descriptor->u.Memory.MinimumAddress.QuadPart = (ULONGLONG)Base;
+        Descriptor->u.Memory.MaximumAddress.QuadPart = (ULONGLONG)(Base + Length - 1);
+      }
+      Descriptor++;
+
+      /* Set alternative descriptor */
+      Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
+      if (Flags & PCI_ADDRESS_IO_SPACE)
+      {
+        Descriptor->Type = CmResourceTypePort;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_PORT_IO |
+                            CM_RESOURCE_PORT_16_BIT_DECODE |
+                            CM_RESOURCE_PORT_POSITIVE_DECODE;
+
+        Descriptor->u.Port.Length = Length;
+        Descriptor->u.Port.Alignment = Length;
+        Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
+        Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
+      }
+      else
+      {
+        Descriptor->Type = CmResourceTypeMemory;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+
+        Descriptor->u.Memory.Length = Length;
+        Descriptor->u.Memory.Alignment = Length;
+        Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
+        Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
+      }
+      Descriptor++;
+    }
+    if (DeviceExtension->PciDevice->PciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV)
+    {
+      Descriptor->Option = 0; /* Required */
+      Descriptor->Type = CmResourceTypeBusNumber;
+      Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+
+      Descriptor->u.BusNumber.MinBusNumber =
+      Descriptor->u.BusNumber.MaxBusNumber = DeviceExtension->PciDevice->PciConfig.u.type1.SecondaryBus;
+      Descriptor->u.BusNumber.Length = 1;
+      Descriptor->u.BusNumber.Reserved = 0;
+    }
+  }
+  else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
+  {
+    /* FIXME: Add Cardbus bridge resources */
+  }
+
+  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+
+  return STATUS_SUCCESS;
 }
 
 
@@ -335,7 +614,7 @@ PdoQueryResources(
   PCM_PARTIAL_RESOURCE_LIST PartialList;
   PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
   ULONG Size;
-  ULONG ResCount;
+  ULONG ResCount = 0;
   ULONG ListSize;
   ULONG i;
   ULONG Base;
@@ -348,12 +627,12 @@ PdoQueryResources(
 
   /* 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;
@@ -363,58 +642,79 @@ PdoQueryResources(
 
   /* Count required resource descriptors */
   ResCount = 0;
-  if ((PciConfig.HeaderType & 0x7F) == 0)
+  if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
   {
     for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
     {
-      if (PciConfig.u.type0.BaseAddresses[i] == 0)
+      if (!PdoGetRangeLength(DeviceExtension,
+                            0x10 + i * 4,
+                            &Base,
+                            &Length,
+                            &Flags))
         break;
 
-      ResCount++;
+      if (Length)
+        ResCount++;
     }
 
-    if (PciConfig.u.type0.InterruptLine != 0xFF)
+    if ((PciConfig.u.type0.InterruptPin != 0) &&
+        (PciConfig.u.type0.InterruptLine != 0xFF))
       ResCount++;
   }
-  else if ((PciConfig.HeaderType & 0x7F) == 1)
+  else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
   {
     for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
     {
-      if (PciConfig.u.type0.BaseAddresses[i] != 0)
+      if (!PdoGetRangeLength(DeviceExtension,
+                            0x10 + i * 4,
+                            &Base,
+                            &Length,
+                            &Flags))
         break;
 
-      ResCount++;
+      if (Length != 0)
+        ResCount++;
     }
+    if (DeviceExtension->PciDevice->PciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV)
+      ResCount++;
+  }
+  else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
+  {
+    /* FIXME: Count Cardbus bridge resources */
   }
   else
   {
-    DPRINT1("Unsupported header type %u\n", PciConfig.HeaderType);
+    DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig));
   }
 
-  /* Calculate the resource list size */
-  ListSize = sizeof(CM_RESOURCE_LIST);
-  if (ResCount > 1)
+  if (ResCount == 0)
   {
-    ListSize += ((ResCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
+    Irp->IoStatus.Information = 0;
+    return STATUS_SUCCESS;
   }
 
+  /* Calculate the resource list size */
+  ListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List->PartialResourceList.PartialDescriptors)
+    + ResCount * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+
   /* Allocate the resource list */
   ResourceList = ExAllocatePool(PagedPool,
                                 ListSize);
   if (ResourceList == NULL)
     return STATUS_INSUFFICIENT_RESOURCES;
 
+  RtlZeroMemory(ResourceList, ListSize);
   ResourceList->Count = 1;
-  ResourceList->List[0].InterfaceType = PCIConfiguration;
-  ResourceList->List[0].BusNumber = DeviceExtension->BusNumber;
+  ResourceList->List[0].InterfaceType = PCIBus;
+  ResourceList->List[0].BusNumber = DeviceExtension->PciDevice->BusNumber;
 
   PartialList = &ResourceList->List[0].PartialResourceList;
-  PartialList->Version = 0;
-  PartialList->Revision = 0;
+  PartialList->Version = 1;
+  PartialList->Revision = 1;
   PartialList->Count = ResCount;
 
   Descriptor = &PartialList->PartialDescriptors[0];
-  if ((PciConfig.HeaderType & 0x7F) == 0)
+  if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
   {
     for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
     {
@@ -431,13 +731,13 @@ PdoQueryResources(
       if (Length == 0)
       {
         DPRINT("Unused address register\n");
-        break;
+        continue;
       }
 
       if (Flags & PCI_ADDRESS_IO_SPACE)
       {
         Descriptor->Type = CmResourceTypePort;
-//        Descriptor->ShareDisposition =
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
         Descriptor->Flags = CM_RESOURCE_PORT_IO;
         Descriptor->u.Port.Start.QuadPart =
           (ULONGLONG)Base;
@@ -446,7 +746,7 @@ PdoQueryResources(
       else
       {
         Descriptor->Type = CmResourceTypeMemory;
-//        Descriptor->ShareDisposition =
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
         Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
         Descriptor->u.Memory.Start.QuadPart =
           (ULONGLONG)Base;
@@ -456,26 +756,73 @@ PdoQueryResources(
       Descriptor++;
     }
 
-    if (PciConfig.u.type0.InterruptLine != 0xFF)
+    /* Add interrupt resource */
+    if ((PciConfig.u.type0.InterruptPin != 0) &&
+        (PciConfig.u.type0.InterruptLine != 0xFF))
     {
       Descriptor->Type = CmResourceTypeInterrupt;
-//      Descriptor->ShareDisposition =
+      Descriptor->ShareDisposition = CmResourceShareShared;
       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)
+  else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
   {
     for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
     {
-      if (PciConfig.u.type0.BaseAddresses[i] != 0)
-        ResCount++;
+      if (!PdoGetRangeLength(DeviceExtension,
+                            0x10 + i * 4,
+                            &Base,
+                            &Length,
+                            &Flags))
+      {
+        DPRINT1("PdoGetRangeLength() failed\n");
+        break;
+      }
+
+      if (Length == 0)
+      {
+        DPRINT("Unused address register\n");
+        continue;
+      }
+
+      if (Flags & PCI_ADDRESS_IO_SPACE)
+      {
+        Descriptor->Type = CmResourceTypePort;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_PORT_IO;
+        Descriptor->u.Port.Start.QuadPart =
+          (ULONGLONG)Base;
+        Descriptor->u.Port.Length = Length;
+      }
+      else
+      {
+        Descriptor->Type = CmResourceTypeMemory;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+        Descriptor->u.Memory.Start.QuadPart =
+          (ULONGLONG)Base;
+        Descriptor->u.Memory.Length = Length;
+      }
+
+      Descriptor++;
+    }
+    if (DeviceExtension->PciDevice->PciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV)
+    {
+      Descriptor->Type = CmResourceTypeBusNumber;
+      Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+
+      Descriptor->u.BusNumber.Start = DeviceExtension->PciDevice->PciConfig.u.type1.SecondaryBus;
+      Descriptor->u.BusNumber.Length = 1;
+      Descriptor->u.BusNumber.Reserved = 0;
     }
   }
-#endif
+  else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
+  {
+    /* FIXME: Add Cardbus bridge resources */
+  }
 
   Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
 
@@ -483,31 +830,367 @@ PdoQueryResources(
 }
 
 
+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;
+
+  DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
+    Context, BusAddress, Length, AddressSpace, TranslatedAddress);
+
+  DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
+
+  return HalTranslateBusAddress(
+    PCIBus, DeviceExtension->PciDevice->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(%p 0x%lx %p 0x%lx 0x%lx)\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(%p 0x%lx %p 0x%lx 0x%lx) 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 BOOLEAN NTAPI
+InterfacePciDevicePresent(
+  IN USHORT VendorID,
+  IN USHORT DeviceID,
+  IN UCHAR RevisionID,
+  IN USHORT SubVendorID,
+  IN USHORT SubSystemID,
+  IN ULONG Flags)
+{
+  PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+  PPCI_DEVICE PciDevice;
+  PLIST_ENTRY CurrentBus, CurrentEntry;
+  KIRQL OldIrql;
+  BOOLEAN Found = FALSE;
+
+  KeAcquireSpinLock(&DriverExtension->BusListLock, &OldIrql);
+  CurrentBus = DriverExtension->BusListHead.Flink;
+  while (!Found && CurrentBus != &DriverExtension->BusListHead)
+  {
+    FdoDeviceExtension = CONTAINING_RECORD(CurrentBus, FDO_DEVICE_EXTENSION, ListEntry);
+
+    KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension->DeviceListLock);
+    CurrentEntry = FdoDeviceExtension->DeviceListHead.Flink;
+    while (!Found && CurrentEntry != &FdoDeviceExtension->DeviceListHead)
+    {
+      PciDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
+      if (PciDevice->PciConfig.VendorID == VendorID &&
+        PciDevice->PciConfig.DeviceID == DeviceID)
+      {
+        if (!(Flags & PCI_USE_SUBSYSTEM_IDS) || (
+          PciDevice->PciConfig.u.type0.SubVendorID == SubVendorID &&
+          PciDevice->PciConfig.u.type0.SubSystemID == SubSystemID))
+        {
+          if (!(Flags & PCI_USE_REVISION) ||
+            PciDevice->PciConfig.RevisionID == RevisionID)
+          {
+            DPRINT("Found the PCI device\n");
+            Found = TRUE;
+          }
+        }
+      }
+
+      CurrentEntry = CurrentEntry->Flink;
+    }
+
+    KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension->DeviceListLock);
+    CurrentBus = CurrentBus->Flink;
+  }
+  KeReleaseSpinLock(&DriverExtension->BusListLock, OldIrql);
+
+  return Found;
+}
+
+
+static BOOLEAN
+CheckPciDevice(
+  IN PPCI_COMMON_CONFIG PciConfig,
+  IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters)
+{
+  if ((Parameters->Flags & PCI_USE_VENDEV_IDS) && (
+    PciConfig->VendorID != Parameters->VendorID ||
+    PciConfig->DeviceID != Parameters->DeviceID))
+  {
+    return FALSE;
+  }
+  if ((Parameters->Flags & PCI_USE_CLASS_SUBCLASS) && (
+    PciConfig->BaseClass != Parameters->BaseClass ||
+    PciConfig->SubClass != Parameters->SubClass))
+  {
+    return FALSE;
+  }
+  if ((Parameters->Flags & PCI_USE_PROGIF) &&
+    PciConfig->ProgIf != Parameters->ProgIf)
+  {
+    return FALSE;
+  }
+  if ((Parameters->Flags & PCI_USE_SUBSYSTEM_IDS) && (
+    PciConfig->u.type0.SubVendorID != Parameters->SubVendorID ||
+    PciConfig->u.type0.SubSystemID != Parameters->SubSystemID))
+  {
+    return FALSE;
+  }
+  if ((Parameters->Flags & PCI_USE_REVISION) &&
+    PciConfig->RevisionID != Parameters->RevisionID)
+  {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+
+static BOOLEAN NTAPI
+InterfacePciDevicePresentEx(
+  IN PVOID Context,
+  IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters)
+{
+  PPDO_DEVICE_EXTENSION DeviceExtension;
+  PFDO_DEVICE_EXTENSION MyFdoDeviceExtension;
+  PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+  PPCI_DEVICE PciDevice;
+  PLIST_ENTRY CurrentBus, CurrentEntry;
+  KIRQL OldIrql;
+  BOOLEAN Found = FALSE;
+
+  DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
+    Context, Parameters);
+
+  if (!Parameters || Parameters->Size != sizeof(PCI_DEVICE_PRESENCE_PARAMETERS))
+    return FALSE;
+
+  DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
+  MyFdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->Fdo->DeviceExtension;
+
+  if (Parameters->Flags & PCI_USE_LOCAL_DEVICE)
+  {
+    return CheckPciDevice(&DeviceExtension->PciDevice->PciConfig, Parameters);
+  }
+
+  KeAcquireSpinLock(&DriverExtension->BusListLock, &OldIrql);
+  CurrentBus = DriverExtension->BusListHead.Flink;
+  while (!Found && CurrentBus != &DriverExtension->BusListHead)
+  {
+    FdoDeviceExtension = CONTAINING_RECORD(CurrentBus, FDO_DEVICE_EXTENSION, ListEntry);
+    if (!(Parameters->Flags & PCI_USE_LOCAL_BUS) || FdoDeviceExtension == MyFdoDeviceExtension)
+    {
+      KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension->DeviceListLock);
+      CurrentEntry = FdoDeviceExtension->DeviceListHead.Flink;
+      while (!Found && CurrentEntry != &FdoDeviceExtension->DeviceListHead)
+      {
+        PciDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
+
+        if (CheckPciDevice(&PciDevice->PciConfig, Parameters))
+        {
+          DPRINT("Found the PCI device\n");
+          Found = TRUE;
+        }
+
+        CurrentEntry = CurrentEntry->Flink;
+      }
+
+      KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension->DeviceListLock);
+    }
+    CurrentBus = CurrentBus->Flink;
+  }
+  KeReleaseSpinLock(&DriverExtension->BusListLock, OldIrql);
+
+  return Found;
+}
+
+
+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->TranslateBusAddress = InterfaceBusTranslateBusAddress;
+      BusInterface->GetDmaAdapter = InterfaceBusGetDmaAdapter;
+      BusInterface->SetBusData = InterfaceBusSetBusData;
+      BusInterface->GetBusData = InterfaceBusGetBusData;
+      Status = STATUS_SUCCESS;
+    }
+  }
+  else if (RtlCompareMemory(IrpSp->Parameters.QueryInterface.InterfaceType,
+    &GUID_PCI_DEVICE_PRESENT_INTERFACE, sizeof(GUID)) == sizeof(GUID))
+  {
+    /* PCI_DEVICE_PRESENT_INTERFACE */
+    if (IrpSp->Parameters.QueryInterface.Version < 1)
+      Status = STATUS_NOT_SUPPORTED;
+    else if (IrpSp->Parameters.QueryInterface.Size < sizeof(PCI_DEVICE_PRESENT_INTERFACE))
+      Status = STATUS_BUFFER_TOO_SMALL;
+    else
+    {
+      PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface;
+      PciDevicePresentInterface = (PPCI_DEVICE_PRESENT_INTERFACE)IrpSp->Parameters.QueryInterface.Interface;
+      PciDevicePresentInterface->Size = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
+      PciDevicePresentInterface->Version = 1;
+      PciDevicePresentInterface->IsDevicePresent = InterfacePciDevicePresent;
+      PciDevicePresentInterface->IsDevicePresentEx = InterfacePciDevicePresentEx;
+      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->Context = DeviceObject;
+    Interface->InterfaceReference = InterfaceReference;
+    Interface->InterfaceDereference = InterfaceDereference;
+    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");
+  DPRINT("PdoReadConfig() called\n");
 
-  DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+  Size = InterfaceBusGetBusData(
+    DeviceObject,
+    IrpSp->Parameters.ReadWriteConfig.WhichSpace,
+    IrpSp->Parameters.ReadWriteConfig.Buffer,
+    IrpSp->Parameters.ReadWriteConfig.Offset,
+    IrpSp->Parameters.ReadWriteConfig.Length);
 
-#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);
@@ -527,25 +1210,18 @@ PdoWriteConfig(
   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);
@@ -612,12 +1288,6 @@ PdoPnpControl(
 
   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;
 
@@ -652,9 +1322,6 @@ PdoPnpControl(
 #if 0
   case IRP_MN_QUERY_PNP_DEVICE_STATE:
     break;
-
-  case IRP_MN_QUERY_REMOVE_DEVICE:
-    break;
 #endif
 
   case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
@@ -668,37 +1335,38 @@ PdoPnpControl(
     break;
 
 #if 0
-  case IRP_MN_QUERY_STOP_DEVICE:
-    break;
-
-  case IRP_MN_REMOVE_DEVICE:
-    break;
-
   case IRP_MN_SET_LOCK:
     break;
+#endif
 
   case IRP_MN_START_DEVICE:
-    break;
-
+  case IRP_MN_QUERY_STOP_DEVICE:
+  case IRP_MN_CANCEL_STOP_DEVICE:
   case IRP_MN_STOP_DEVICE:
+  case IRP_MN_QUERY_REMOVE_DEVICE:
+  case IRP_MN_CANCEL_REMOVE_DEVICE:
+  case IRP_MN_REMOVE_DEVICE:
+  case IRP_MN_SURPRISE_REMOVAL:
+    Status = STATUS_SUCCESS;
     break;
 
-  case IRP_MN_SURPRISE_REMOVAL:
+  case IRP_MN_QUERY_INTERFACE:
+    DPRINT("IRP_MN_QUERY_INTERFACE received\n");
+    Status = PdoQueryInterface(DeviceObject, Irp, IrpSp);
     break;
-#endif
 
   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;
   }