[PCI]
[reactos.git] / reactos / drivers / bus / pci / pdo.c
index 6440d40..bca71c1 100644 (file)
@@ -21,6 +21,9 @@
 #define DBGPRINT(...)
 #endif
 
+#define PCI_ADDRESS_MEMORY_ADDRESS_MASK_64     0xfffffffffffffff0ull
+#define PCI_ADDRESS_IO_ADDRESS_MASK_64         0xfffffffffffffffcull
+
 /*** PRIVATE *****************************************************************/
 
 static NTSTATUS
@@ -191,60 +194,49 @@ PdoQueryCapabilities(
     return STATUS_SUCCESS;
 }
 
-
 static BOOLEAN
-PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension,
-                  ULONG Offset,
-                  PULONG Base,
-                  PULONG Length,
-                  PULONG Flags)
+PdoReadPciBar(PPDO_DEVICE_EXTENSION DeviceExtension,
+              ULONG Offset,
+              PULONG OriginalValue,
+              PULONG NewValue)
 {
-    ULONG OrigValue;
-    ULONG BaseValue;
-    ULONG NewValue;
     ULONG Size;
-    ULONG XLength;
-
-    /* Save original value */
-    Size= HalGetBusDataByOffset(PCIConfiguration,
-                                DeviceExtension->PciDevice->BusNumber,
-                                DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
-                                &OrigValue,
-                                Offset,
-                                sizeof(ULONG));
+    ULONG AllOnes;
+    
+    /* Read the original value */
+    Size = HalGetBusDataByOffset(PCIConfiguration,
+                                 DeviceExtension->PciDevice->BusNumber,
+                                 DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+                                 OriginalValue,
+                                 Offset,
+                                 sizeof(ULONG));
     if (Size != sizeof(ULONG))
     {
         DPRINT1("Wrong size %lu\n", Size);
         return FALSE;
     }
-
-    BaseValue = (OrigValue & PCI_ADDRESS_IO_SPACE)
-                ? (OrigValue & PCI_ADDRESS_IO_ADDRESS_MASK)
-                : (OrigValue & PCI_ADDRESS_MEMORY_ADDRESS_MASK);
-
-    *Base = BaseValue;
-
-    /* Set magic value */
-    NewValue = MAXULONG;
-    Size= HalSetBusDataByOffset(PCIConfiguration,
-                                DeviceExtension->PciDevice->BusNumber,
-                                DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
-                                &NewValue,
-                                Offset,
-                                sizeof(ULONG));
+    
+    /* Write all ones to determine which bits are held to zero */
+    AllOnes = MAXULONG;
+    Size = HalSetBusDataByOffset(PCIConfiguration,
+                                 DeviceExtension->PciDevice->BusNumber,
+                                 DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+                                 &AllOnes,
+                                 Offset,
+                                 sizeof(ULONG));
     if (Size != sizeof(ULONG))
     {
         DPRINT1("Wrong size %lu\n", Size);
         return FALSE;
     }
-
+    
     /* Get the range length */
-    Size= HalGetBusDataByOffset(PCIConfiguration,
-                                DeviceExtension->PciDevice->BusNumber,
-                                DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
-                                &NewValue,
-                                Offset,
-                                sizeof(ULONG));
+    Size = HalGetBusDataByOffset(PCIConfiguration,
+                                 DeviceExtension->PciDevice->BusNumber,
+                                 DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+                                 NewValue,
+                                 Offset,
+                                 sizeof(ULONG));
     if (Size != sizeof(ULONG))
     {
         DPRINT1("Wrong size %lu\n", Size);
@@ -252,68 +244,126 @@ PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension,
     }
 
     /* Restore original value */
-    Size= HalSetBusDataByOffset(PCIConfiguration,
-                                DeviceExtension->PciDevice->BusNumber,
-                                DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
-                                &OrigValue,
-                                Offset,
-                                sizeof(ULONG));
+    Size = HalSetBusDataByOffset(PCIConfiguration,
+                                 DeviceExtension->PciDevice->BusNumber,
+                                 DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+                                 OriginalValue,
+                                 Offset,
+                                 sizeof(ULONG));
     if (Size != sizeof(ULONG))
     {
         DPRINT1("Wrong size %lu\n", Size);
         return FALSE;
     }
+    
+    return TRUE;
+}
 
-    if (NewValue == 0)
-    {
-        DPRINT("Unused address register\n");
-        *Base = 0;
-        *Length = 0;
-        *Flags = 0;
-        return TRUE;
-    }
-
-    XLength = ~((NewValue & PCI_ADDRESS_IO_SPACE)
-                ? (NewValue & PCI_ADDRESS_IO_ADDRESS_MASK)
-                : (NewValue & PCI_ADDRESS_MEMORY_ADDRESS_MASK)) + 1;
-
-#if 0
-    DbgPrint("BaseAddress 0x%08lx  Length 0x%08lx",
-             BaseValue, XLength);
-
-    if (NewValue & PCI_ADDRESS_IO_SPACE)
+static BOOLEAN
+PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension,
+                  UCHAR Bar,
+                  PULONGLONG Base,
+                  PULONGLONG Length,
+                  PULONG Flags,
+                  PUCHAR NextBar,
+                  PULONGLONG MaximumAddress)
+{
+    union {
+        struct {
+            ULONG Bar0;
+            ULONG Bar1;
+        } Bars;
+        ULONGLONG Bar;
+    } OriginalValue;
+    union {
+        struct {
+            ULONG Bar0;
+            ULONG Bar1;
+        } Bars;
+        ULONGLONG Bar;
+    } NewValue;
+    ULONG Offset;
+    
+    /* Compute the offset of this BAR in PCI config space */
+    Offset = 0x10 + Bar * 4;
+    
+    /* Assume this is a 32-bit BAR until we find wrong */
+    *NextBar = Bar + 1;
+    
+    /* Initialize BAR values to zero */
+    OriginalValue.Bar = 0ULL;
+    NewValue.Bar = 0ULL;
+
+    /* Read the first BAR */
+    if (!PdoReadPciBar(DeviceExtension, Offset,
+                       &OriginalValue.Bars.Bar0,
+                       &NewValue.Bars.Bar0))
     {
-        DbgPrint("  IO range");
+        return FALSE;
     }
-    else
+    
+    /* Check if this is a memory BAR */
+    if (!(OriginalValue.Bars.Bar0 & PCI_ADDRESS_IO_SPACE))
     {
-        DbgPrint("  Memory range");
-        if ((NewValue & PCI_ADDRESS_MEMORY_TYPE_MASK) == 0)
+        /* Write the maximum address if the caller asked for it */
+        if (MaximumAddress != NULL)
         {
-            DbgPrint(" in 32-Bit address space");
+            if ((OriginalValue.Bars.Bar0 & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_32BIT)
+            {
+                *MaximumAddress = 0x00000000FFFFFFFFULL;
+            }
+            else if ((OriginalValue.Bars.Bar0 & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_20BIT)
+            {
+                *MaximumAddress = 0x00000000000FFFFFULL;
+            }
+            else if ((OriginalValue.Bars.Bar0 & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)
+            {
+                *MaximumAddress = 0xFFFFFFFFFFFFFFFFULL;
+            }
         }
-        else if ((NewValue & PCI_ADDRESS_MEMORY_TYPE_MASK) == 2)
+        
+        /* Check if this is a 64-bit BAR */
+        if ((OriginalValue.Bars.Bar0 & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)
         {
-            DbgPrint(" below 1BM ");
+            /* We've now consumed the next BAR too */
+            *NextBar = Bar + 2;
+            
+            /* Read the next BAR */
+            if (!PdoReadPciBar(DeviceExtension, Offset + 4,
+                               &OriginalValue.Bars.Bar1,
+                               &NewValue.Bars.Bar1))
+            {
+                return FALSE;
+            }
         }
-        else if ((NewValue & PCI_ADDRESS_MEMORY_TYPE_MASK) == 4)
+    }
+    else
+    {
+        /* Write the maximum I/O port address */
+        if (MaximumAddress != NULL)
         {
-            DbgPrint(" in 64-Bit address space");
+            *MaximumAddress = 0x00000000FFFFFFFFULL;
         }
+    }
 
-        if (NewValue & PCI_ADDRESS_MEMORY_PREFETCHABLE)
-        {
-            DbgPrint(" prefetchable");
-        }
+    if (NewValue.Bar == 0)
+    {
+        DPRINT("Unused address register\n");
+        *Base = 0;
+        *Length = 0;
+        *Flags = 0;
+        return TRUE;
     }
+    
+    *Base = OriginalValue.Bar & PCI_ADDRESS_MEMORY_ADDRESS_MASK_64;
 
-    DbgPrint("\n");
-#endif
+    *Length = ~((NewValue.Bar & PCI_ADDRESS_IO_SPACE)
+                ? (NewValue.Bar & PCI_ADDRESS_IO_ADDRESS_MASK_64)
+                : (NewValue.Bar & PCI_ADDRESS_MEMORY_ADDRESS_MASK_64)) + 1;
 
-    *Length = XLength;
-    *Flags = (NewValue & PCI_ADDRESS_IO_SPACE)
-             ? (NewValue & ~PCI_ADDRESS_IO_ADDRESS_MASK)
-             : (NewValue & ~PCI_ADDRESS_MEMORY_ADDRESS_MASK);
+    *Flags = (NewValue.Bar & PCI_ADDRESS_IO_SPACE)
+             ? (NewValue.Bar & ~PCI_ADDRESS_IO_ADDRESS_MASK_64)
+             : (NewValue.Bar & ~PCI_ADDRESS_MEMORY_ADDRESS_MASK_64);
 
     return TRUE;
 }
@@ -332,10 +382,11 @@ PdoQueryResourceRequirements(
     ULONG Size;
     ULONG ResCount = 0;
     ULONG ListSize;
-    ULONG i;
-    ULONG Base;
-    ULONG Length;
+    UCHAR Bar;
+    ULONGLONG Base;
+    ULONGLONG Length;
     ULONG Flags;
+    ULONGLONG MaximumAddress;
 
     UNREFERENCED_PARAMETER(IrpSp);
     DPRINT("PdoQueryResourceRequirements() called\n");
@@ -361,13 +412,15 @@ PdoQueryResourceRequirements(
     ResCount = 0;
     if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
     {
-        for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
+        for (Bar = 0; Bar < PCI_TYPE0_ADDRESSES;)
         {
             if (!PdoGetRangeLength(DeviceExtension,
-                                   0x10 + i * 4,
+                                   Bar,
                                    &Base,
                                    &Length,
-                                   &Flags))
+                                   &Flags,
+                                   &Bar,
+                                   NULL))
                 break;
 
             if (Length != 0)
@@ -381,13 +434,15 @@ PdoQueryResourceRequirements(
     }
     else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
     {
-        for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
+        for (Bar = 0; Bar < PCI_TYPE1_ADDRESSES;)
         {
             if (!PdoGetRangeLength(DeviceExtension,
-                                   0x10 + i * 4,
+                                   Bar,
                                    &Base,
                                    &Length,
-                                   &Flags))
+                                   &Flags,
+                                   &Bar,
+                                   NULL))
                 break;
 
             if (Length != 0)
@@ -442,13 +497,15 @@ PdoQueryResourceRequirements(
     Descriptor = &ResourceList->List[0].Descriptors[0];
     if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
     {
-        for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
+        for (Bar = 0; Bar < PCI_TYPE0_ADDRESSES;)
         {
             if (!PdoGetRangeLength(DeviceExtension,
-                                   0x10 + i * 4,
+                                   Bar,
                                    &Base,
                                    &Length,
-                                   &Flags))
+                                   &Flags,
+                                   &Bar,
+                                   &MaximumAddress))
             {
                 DPRINT1("PdoGetRangeLength() failed\n");
                 break;
@@ -472,19 +529,20 @@ PdoQueryResourceRequirements(
 
                 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);
+                Descriptor->u.Port.MinimumAddress.QuadPart = Base;
+                Descriptor->u.Port.MaximumAddress.QuadPart = Base + Length - 1;
             }
             else
             {
                 Descriptor->Type = CmResourceTypeMemory;
                 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE |
+                    (Flags & PCI_ADDRESS_MEMORY_PREFETCHABLE) ? CM_RESOURCE_MEMORY_PREFETCHABLE : 0;
 
                 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->u.Memory.MinimumAddress.QuadPart = Base;
+                Descriptor->u.Memory.MaximumAddress.QuadPart = Base + Length - 1;
             }
             Descriptor++;
 
@@ -500,19 +558,20 @@ PdoQueryResourceRequirements(
 
                 Descriptor->u.Port.Length = Length;
                 Descriptor->u.Port.Alignment = Length;
-                Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
-                Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
+                Descriptor->u.Port.MinimumAddress.QuadPart = 0;
+                Descriptor->u.Port.MaximumAddress.QuadPart = MaximumAddress;
             }
             else
             {
                 Descriptor->Type = CmResourceTypeMemory;
                 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE |
+                    (Flags & PCI_ADDRESS_MEMORY_PREFETCHABLE) ? CM_RESOURCE_MEMORY_PREFETCHABLE : 0;
 
                 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->u.Port.MinimumAddress.QuadPart = 0;
+                Descriptor->u.Port.MaximumAddress.QuadPart = MaximumAddress;
             }
             Descriptor++;
         }
@@ -532,13 +591,15 @@ PdoQueryResourceRequirements(
     }
     else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
     {
-        for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
+        for (Bar = 0; Bar < PCI_TYPE1_ADDRESSES;)
         {
             if (!PdoGetRangeLength(DeviceExtension,
-                                   0x10 + i * 4,
+                                   Bar,
                                    &Base,
                                    &Length,
-                                   &Flags))
+                                   &Flags,
+                                   &Bar,
+                                   &MaximumAddress))
             {
                 DPRINT1("PdoGetRangeLength() failed\n");
                 break;
@@ -562,19 +623,20 @@ PdoQueryResourceRequirements(
 
                 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);
+                Descriptor->u.Port.MinimumAddress.QuadPart = Base;
+                Descriptor->u.Port.MaximumAddress.QuadPart = Base + Length - 1;
             }
             else
             {
                 Descriptor->Type = CmResourceTypeMemory;
                 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE |
+                    (Flags & PCI_ADDRESS_MEMORY_PREFETCHABLE) ? CM_RESOURCE_MEMORY_PREFETCHABLE : 0;
 
                 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->u.Memory.MinimumAddress.QuadPart = Base;
+                Descriptor->u.Memory.MaximumAddress.QuadPart = Base + Length - 1;
             }
             Descriptor++;
 
@@ -590,19 +652,20 @@ PdoQueryResourceRequirements(
 
                 Descriptor->u.Port.Length = Length;
                 Descriptor->u.Port.Alignment = Length;
-                Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
-                Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
+                Descriptor->u.Port.MinimumAddress.QuadPart = 0;
+                Descriptor->u.Port.MaximumAddress.QuadPart = MaximumAddress;
             }
             else
             {
                 Descriptor->Type = CmResourceTypeMemory;
                 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE |
+                    (Flags & PCI_ADDRESS_MEMORY_PREFETCHABLE) ? CM_RESOURCE_MEMORY_PREFETCHABLE : 0;
 
                 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->u.Port.MinimumAddress.QuadPart = 0;
+                Descriptor->u.Port.MaximumAddress.QuadPart = MaximumAddress;
             }
             Descriptor++;
         }
@@ -645,9 +708,9 @@ PdoQueryResources(
     ULONG Size;
     ULONG ResCount = 0;
     ULONG ListSize;
-    ULONG i;
-    ULONG Base;
-    ULONG Length;
+    UCHAR Bar;
+    ULONGLONG Base;
+    ULONGLONG Length;
     ULONG Flags;
 
     DPRINT("PdoQueryResources() called\n");
@@ -674,13 +737,15 @@ PdoQueryResources(
     ResCount = 0;
     if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
     {
-        for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
+        for (Bar = 0; Bar < PCI_TYPE0_ADDRESSES;)
         {
             if (!PdoGetRangeLength(DeviceExtension,
-                                   0x10 + i * 4,
+                                   Bar,
                                    &Base,
                                    &Length,
-                                   &Flags))
+                                   &Flags,
+                                   &Bar,
+                                   NULL))
                 break;
 
             if (Length)
@@ -694,13 +759,15 @@ PdoQueryResources(
     }
     else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
     {
-        for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
+        for (Bar = 0; Bar < PCI_TYPE1_ADDRESSES;)
         {
             if (!PdoGetRangeLength(DeviceExtension,
-                                   0x10 + i * 4,
+                                   Bar,
                                    &Base,
                                    &Length,
-                                   &Flags))
+                                   &Flags,
+                                   &Bar,
+                                   NULL))
                 break;
 
             if (Length != 0)
@@ -749,17 +816,16 @@ PdoQueryResources(
     Descriptor = &PartialList->PartialDescriptors[0];
     if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
     {
-        for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
+        for (Bar = 0; Bar < PCI_TYPE0_ADDRESSES;)
         {
             if (!PdoGetRangeLength(DeviceExtension,
-                                   0x10 + i * 4,
+                                   Bar,
                                    &Base,
                                    &Length,
-                                   &Flags))
-            {
-                DPRINT1("PdoGetRangeLength() failed\n");
+                                   &Flags,
+                                   &Bar,
+                                   NULL))
                 break;
-            }
 
             if (Length == 0)
             {
@@ -771,7 +837,9 @@ PdoQueryResources(
             {
                 Descriptor->Type = CmResourceTypePort;
                 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-                Descriptor->Flags = CM_RESOURCE_PORT_IO;
+                Descriptor->Flags = CM_RESOURCE_PORT_IO |
+                                    CM_RESOURCE_PORT_16_BIT_DECODE |
+                                    CM_RESOURCE_PORT_POSITIVE_DECODE;
                 Descriptor->u.Port.Start.QuadPart = (ULONGLONG)Base;
                 Descriptor->u.Port.Length = Length;
 
@@ -782,7 +850,8 @@ PdoQueryResources(
             {
                 Descriptor->Type = CmResourceTypeMemory;
                 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE |
+                    (Flags & PCI_ADDRESS_MEMORY_PREFETCHABLE) ? CM_RESOURCE_MEMORY_PREFETCHABLE : 0;
                 Descriptor->u.Memory.Start.QuadPart = (ULONGLONG)Base;
                 Descriptor->u.Memory.Length = Length;
 
@@ -811,17 +880,16 @@ PdoQueryResources(
     }
     else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
     {
-        for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
+        for (Bar = 0; Bar < PCI_TYPE1_ADDRESSES;)
         {
             if (!PdoGetRangeLength(DeviceExtension,
-                                   0x10 + i * 4,
+                                   Bar,
                                    &Base,
                                    &Length,
-                                   &Flags))
-            {
-                DPRINT1("PdoGetRangeLength() failed\n");
+                                   &Flags,
+                                   &Bar,
+                                   NULL))
                 break;
-            }
 
             if (Length == 0)
             {
@@ -833,7 +901,9 @@ PdoQueryResources(
             {
                 Descriptor->Type = CmResourceTypePort;
                 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-                Descriptor->Flags = CM_RESOURCE_PORT_IO;
+                Descriptor->Flags = CM_RESOURCE_PORT_IO |
+                                    CM_RESOURCE_PORT_16_BIT_DECODE |
+                                    CM_RESOURCE_PORT_POSITIVE_DECODE;
                 Descriptor->u.Port.Start.QuadPart = (ULONGLONG)Base;
                 Descriptor->u.Port.Length = Length;
 
@@ -844,7 +914,8 @@ PdoQueryResources(
             {
                 Descriptor->Type = CmResourceTypeMemory;
                 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
-                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
+                Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE |
+                    (Flags & PCI_ADDRESS_MEMORY_PREFETCHABLE) ? CM_RESOURCE_MEMORY_PREFETCHABLE : 0;
                 Descriptor->u.Memory.Start.QuadPart = (ULONGLONG)Base;
                 Descriptor->u.Memory.Length = Length;