[NTOSKRNL]
[reactos.git] / ntoskrnl / io / pnpmgr / pnpres.c
index ac1884e..73272f5 100644 (file)
@@ -47,7 +47,7 @@ IopFindBusNumberResource(
    ASSERT(IoDesc->Type == CmResourceTypeBusNumber);
 
    for (Start = IoDesc->u.BusNumber.MinBusNumber;
-        Start < IoDesc->u.BusNumber.MaxBusNumber;
+        Start <= IoDesc->u.BusNumber.MaxBusNumber - IoDesc->u.BusNumber.Length + 1;
         Start++)
    {
         CmDesc->u.BusNumber.Length = IoDesc->u.BusNumber.Length;
@@ -59,6 +59,7 @@ IopFindBusNumberResource(
         }
         else
         {
+            DPRINT1("Satisfying bus number requirement with 0x%x (length: 0x%x)\n", Start, CmDesc->u.BusNumber.Length);
             return TRUE;
         }
    }
@@ -72,25 +73,30 @@ IopFindMemoryResource(
    IN PIO_RESOURCE_DESCRIPTOR IoDesc,
    OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
 {
-   ULONGLONG Start;
+   LONGLONG Start;
    CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
 
    ASSERT(IoDesc->Type == CmDesc->Type);
    ASSERT(IoDesc->Type == CmResourceTypeMemory);
 
+   /* HACK */
+   if (IoDesc->u.Memory.Alignment == 0) IoDesc->u.Memory.Alignment = 1;
+
    for (Start = IoDesc->u.Memory.MinimumAddress.QuadPart;
-        Start < IoDesc->u.Memory.MaximumAddress.QuadPart;
-        Start++)
+        Start <= IoDesc->u.Memory.MaximumAddress.QuadPart - IoDesc->u.Memory.Length + 1;
+        Start += IoDesc->u.Memory.Alignment)
    {
         CmDesc->u.Memory.Length = IoDesc->u.Memory.Length;
         CmDesc->u.Memory.Start.QuadPart = Start;
 
         if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc))
         {
-            Start += ConflictingDesc.u.Memory.Start.QuadPart + ConflictingDesc.u.Memory.Length;
+            Start += ConflictingDesc.u.Memory.Start.QuadPart +
+                     ConflictingDesc.u.Memory.Length;
         }
         else
         {
+            DPRINT1("Satisfying memory requirement with 0x%I64x (length: 0x%x)\n", Start, CmDesc->u.Memory.Length);
             return TRUE;
         }
    }
@@ -104,15 +110,18 @@ IopFindPortResource(
    IN PIO_RESOURCE_DESCRIPTOR IoDesc,
    OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
 {
-   ULONGLONG Start;
+   LONGLONG Start;
    CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
 
    ASSERT(IoDesc->Type == CmDesc->Type);
    ASSERT(IoDesc->Type == CmResourceTypePort);
+    
+   /* HACK */
+   if (IoDesc->u.Port.Alignment == 0) IoDesc->u.Port.Alignment = 1;
 
    for (Start = IoDesc->u.Port.MinimumAddress.QuadPart;
-        Start < IoDesc->u.Port.MaximumAddress.QuadPart;
-        Start++)
+        Start <= IoDesc->u.Port.MaximumAddress.QuadPart - IoDesc->u.Port.Length + 1;
+        Start += IoDesc->u.Port.Alignment)
    {
         CmDesc->u.Port.Length = IoDesc->u.Port.Length;
         CmDesc->u.Port.Start.QuadPart = Start;
@@ -123,6 +132,7 @@ IopFindPortResource(
         }
         else
         {
+            DPRINT1("Satisfying port requirement with 0x%I64x (length: 0x%x)\n", Start, CmDesc->u.Port.Length);
             return TRUE;
         }
    }
@@ -142,14 +152,17 @@ IopFindDmaResource(
    ASSERT(IoDesc->Type == CmResourceTypeDma);
 
    for (Channel = IoDesc->u.Dma.MinimumChannel;
-        Channel < IoDesc->u.Dma.MaximumChannel;
+        Channel <= IoDesc->u.Dma.MaximumChannel;
         Channel++)
    {
         CmDesc->u.Dma.Channel = Channel;
         CmDesc->u.Dma.Port = 0;
 
         if (!IopCheckDescriptorForConflict(CmDesc, NULL))
+        {
+            DPRINT1("Satisfying DMA requirement with channel 0x%x\n", Channel);
             return TRUE;
+        }
    }
 
    return FALSE;
@@ -167,7 +180,7 @@ IopFindInterruptResource(
    ASSERT(IoDesc->Type == CmResourceTypeInterrupt);
 
    for (Vector = IoDesc->u.Interrupt.MinimumVector;
-        Vector < IoDesc->u.Interrupt.MaximumVector;
+        Vector <= IoDesc->u.Interrupt.MaximumVector;
         Vector++)
    {
         CmDesc->u.Interrupt.Vector = Vector;
@@ -175,148 +188,298 @@ IopFindInterruptResource(
         CmDesc->u.Interrupt.Affinity = (KAFFINITY)-1;
 
         if (!IopCheckDescriptorForConflict(CmDesc, NULL))
+        {
+            DPRINT1("Satisfying interrupt requirement with IRQ 0x%x\n", Vector);
             return TRUE;
+        }
    }
 
    return FALSE;
 }
 
-
 NTSTATUS NTAPI
-IopCreateResourceListFromRequirements(
+IopFixupResourceListWithRequirements(
    IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList,
    OUT PCM_RESOURCE_LIST *ResourceList)
 {
-   ULONG i, ii, Size;
-   PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc;
-
-   Size = FIELD_OFFSET(CM_RESOURCE_LIST, List);
-   for (i = 0; i < RequirementsList->AlternativeLists; i++)
-   {
-      PIO_RESOURCE_LIST ResList = &RequirementsList->List[i];
-      Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors)
-        + ResList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-   }
-
-   *ResourceList = ExAllocatePool(PagedPool, Size);
-   if (!*ResourceList)
-       return STATUS_INSUFFICIENT_RESOURCES;
-
-   (*ResourceList)->Count = 1;
-   (*ResourceList)->List[0].BusNumber = RequirementsList->BusNumber;
-   (*ResourceList)->List[0].InterfaceType = RequirementsList->InterfaceType;
-   (*ResourceList)->List[0].PartialResourceList.Version = 1;
-   (*ResourceList)->List[0].PartialResourceList.Revision = 1;
-   (*ResourceList)->List[0].PartialResourceList.Count = 0;
-
-   ResDesc = &(*ResourceList)->List[0].PartialResourceList.PartialDescriptors[0];
-
-   for (i = 0; i < RequirementsList->AlternativeLists; i++)
-   {
-      PIO_RESOURCE_LIST ResList = &RequirementsList->List[i];
-      for (ii = 0; ii < ResList->Count; ii++)
-      {
-         PIO_RESOURCE_DESCRIPTOR ReqDesc = &ResList->Descriptors[ii];
-
-         /* FIXME: Handle alternate ranges */
-         if (ReqDesc->Option == IO_RESOURCE_ALTERNATIVE)
-             continue;
-
-         ResDesc->Type = ReqDesc->Type;
-         ResDesc->Flags = ReqDesc->Flags;
-         ResDesc->ShareDisposition = ReqDesc->ShareDisposition;
-
-         switch (ReqDesc->Type)
-         {
-            case CmResourceTypeInterrupt:
-              if (!IopFindInterruptResource(ReqDesc, ResDesc))
-              {
-                  DPRINT1("Failed to find an available interrupt resource (0x%x to 0x%x)\n",
-                           ReqDesc->u.Interrupt.MinimumVector, ReqDesc->u.Interrupt.MaximumVector);
-
-                  if (ReqDesc->Option == 0)
-                  {
-                      ExFreePool(*ResourceList);
-                      *ResourceList = NULL;
-                      return STATUS_CONFLICTING_ADDRESSES;
-                  }
-              }
-              break;
-
-            case CmResourceTypePort:
-              if (!IopFindPortResource(ReqDesc, ResDesc))
-              {
-                  DPRINT1("Failed to find an available port resource (0x%x to 0x%x length: 0x%x)\n",
-                          ReqDesc->u.Port.MinimumAddress.QuadPart, ReqDesc->u.Port.MaximumAddress.QuadPart,
-                          ReqDesc->u.Port.Length);
-
-                  if (ReqDesc->Option == 0)
-                  {
-                      ExFreePool(*ResourceList);
-                      *ResourceList = NULL;
-                      return STATUS_CONFLICTING_ADDRESSES;
-                  }
-              }
-              break;
-
-            case CmResourceTypeMemory:
-              if (!IopFindMemoryResource(ReqDesc, ResDesc))
-              {
-                  DPRINT1("Failed to find an available memory resource (0x%x to 0x%x length: 0x%x)\n",
-                          ReqDesc->u.Memory.MinimumAddress.QuadPart, ReqDesc->u.Memory.MaximumAddress.QuadPart,
-                          ReqDesc->u.Memory.Length);
-
-                  if (ReqDesc->Option == 0)
-                  {
-                      ExFreePool(*ResourceList);
-                      *ResourceList = NULL;
-                      return STATUS_CONFLICTING_ADDRESSES;
-                  }
-              }
-              break;
-
-            case CmResourceTypeBusNumber:
-              if (!IopFindBusNumberResource(ReqDesc, ResDesc))
-              {
-                  DPRINT1("Failed to find an available bus number resource (0x%x to 0x%x length: 0x%x)\n",
-                          ReqDesc->u.BusNumber.MinBusNumber, ReqDesc->u.BusNumber.MaxBusNumber,
-                          ReqDesc->u.BusNumber.Length);
-
-                  if (ReqDesc->Option == 0)
-                  {
-                      ExFreePool(*ResourceList);
-                      *ResourceList = NULL;
-                      return STATUS_CONFLICTING_ADDRESSES;
-                  }
-              }
-              break;
-
-            case CmResourceTypeDma:
-              if (!IopFindDmaResource(ReqDesc, ResDesc))
-              {
-                  DPRINT1("Failed to find an available dma resource (0x%x to 0x%x)\n",
-                          ReqDesc->u.Dma.MinimumChannel, ReqDesc->u.Dma.MaximumChannel);
+    ULONG i;
+    for (i = 0; i < RequirementsList->AlternativeLists; i++)
+    {
+        ULONG ii;
+        PIO_RESOURCE_LIST ResList = &RequirementsList->List[i];
+        BOOLEAN AlternateRequired = FALSE;
+
+        for (ii = 0; ii < ResList->Count; ii++)
+        {
+            ULONG iii;
+            PCM_PARTIAL_RESOURCE_LIST PartialList = (*ResourceList) ? &(*ResourceList)->List[0].PartialResourceList : NULL;
+            PIO_RESOURCE_DESCRIPTOR IoDesc = &ResList->Descriptors[ii];
+            BOOLEAN Matched = FALSE;
+            
+            /* Skip alternates if we don't need one */
+            if (!AlternateRequired && (IoDesc->Option & IO_RESOURCE_ALTERNATIVE))
+            {
+                DPRINT("Skipping unneeded alternate\n");
+                continue;
+            }
 
-                  if (ReqDesc->Option == 0)
-                  {
-                      ExFreePool(*ResourceList);
-                      *ResourceList = NULL;
-                      return STATUS_CONFLICTING_ADDRESSES;
-                  }
-              }
-              break;
+            /* Check if we couldn't satsify a requirement or its alternates */
+            if (AlternateRequired && !(IoDesc->Option & IO_RESOURCE_ALTERNATIVE))
+            {
+                DPRINT1("Unable to satisfy preferred resource or alternates\n");
+
+                if (*ResourceList)
+                {
+                    ExFreePool(*ResourceList);
+                    *ResourceList = NULL;
+                }
+                return STATUS_CONFLICTING_ADDRESSES;
+            }
 
-            default:
-              DPRINT1("Unsupported resource type: %x\n", ReqDesc->Type);
-              break;
-         }
+            for (iii = 0; PartialList && iii < PartialList->Count && !Matched; iii++)
+            {
+                PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc = &PartialList->PartialDescriptors[iii];
+
+                /* First check types */
+                if (IoDesc->Type != CmDesc->Type)
+                    continue;
+
+                switch (IoDesc->Type)
+                {
+                    case CmResourceTypeInterrupt:
+                        /* Make sure it satisfies our vector range */
+                        if (CmDesc->u.Interrupt.Vector >= IoDesc->u.Interrupt.MinimumVector &&
+                            CmDesc->u.Interrupt.Vector <= IoDesc->u.Interrupt.MaximumVector)
+                        {
+                            /* Found it */
+                            Matched = TRUE;
+                        }
+                        else
+                        {
+                            DPRINT("Interrupt - Not a match! 0x%x not inside 0x%x to 0x%x\n",
+                                   CmDesc->u.Interrupt.Vector,
+                                   IoDesc->u.Interrupt.MinimumVector,
+                                   IoDesc->u.Interrupt.MaximumVector);
+                        }
+                        break;
+
+                    case CmResourceTypeMemory:
+                    case CmResourceTypePort:
+                        /* Make sure the length matches and it satisfies our address range */
+                        if (CmDesc->u.Memory.Length == IoDesc->u.Memory.Length &&
+                            CmDesc->u.Memory.Start.QuadPart >= IoDesc->u.Memory.MinimumAddress.QuadPart &&
+                            CmDesc->u.Memory.Start.QuadPart + CmDesc->u.Memory.Length - 1 <= IoDesc->u.Memory.MaximumAddress.QuadPart)
+                        {
+                            /* Found it */
+                            Matched = TRUE;
+                        }
+                        else
+                        {
+                            DPRINT("Memory/Port - Not a match! 0x%I64x with length 0x%x not inside 0x%I64x to 0x%I64x with length 0x%x\n",
+                                   CmDesc->u.Memory.Start.QuadPart,
+                                   CmDesc->u.Memory.Length,
+                                   IoDesc->u.Memory.MinimumAddress.QuadPart,
+                                   IoDesc->u.Memory.MaximumAddress.QuadPart,
+                                   IoDesc->u.Memory.Length);
+                        }
+                        break;
+
+                    case CmResourceTypeBusNumber:
+                        /* Make sure the length matches and it satisfies our bus number range */
+                        if (CmDesc->u.BusNumber.Length == IoDesc->u.BusNumber.Length &&
+                            CmDesc->u.BusNumber.Start >= IoDesc->u.BusNumber.MinBusNumber &&
+                            CmDesc->u.BusNumber.Start + CmDesc->u.BusNumber.Length - 1 <= IoDesc->u.BusNumber.MaxBusNumber)
+                        {
+                            /* Found it */
+                            Matched = TRUE;
+                        }
+                        else
+                        {
+                            DPRINT("Bus Number - Not a match! 0x%x with length 0x%x not inside 0x%x to 0x%x with length 0x%x\n",
+                                   CmDesc->u.BusNumber.Start,
+                                   CmDesc->u.BusNumber.Length,
+                                   IoDesc->u.BusNumber.MinBusNumber,
+                                   IoDesc->u.BusNumber.MaxBusNumber,
+                                   IoDesc->u.BusNumber.Length);
+                        }
+                        break;
+
+                    case CmResourceTypeDma:
+                        /* Make sure it fits in our channel range */
+                        if (CmDesc->u.Dma.Channel >= IoDesc->u.Dma.MinimumChannel &&
+                            CmDesc->u.Dma.Channel <= IoDesc->u.Dma.MaximumChannel)
+                        {
+                            /* Found it */
+                            Matched = TRUE;
+                        }
+                        else
+                        {
+                            DPRINT("DMA - Not a match! 0x%x not inside 0x%x to 0x%x\n",
+                                   CmDesc->u.Dma.Channel,
+                                   IoDesc->u.Dma.MinimumChannel,
+                                   IoDesc->u.Dma.MaximumChannel);
+                        }
+                        break;
+
+                    default:
+                        /* Other stuff is fine */
+                        Matched = TRUE;
+                        break;
+                }
+            }
 
-         (*ResourceList)->List[0].PartialResourceList.Count++;
-         ResDesc++;
-      }
-   }
+            /* Check if we found a matching descriptor */
+            if (!Matched)
+            {
+                PCM_RESOURCE_LIST NewList;
+                CM_PARTIAL_RESOURCE_DESCRIPTOR NewDesc;
+                PCM_PARTIAL_RESOURCE_DESCRIPTOR DescPtr;
+                BOOLEAN FoundResource = TRUE;
+
+                /* Setup the new CM descriptor */
+                NewDesc.Type = IoDesc->Type;
+                NewDesc.Flags = IoDesc->Flags;
+                NewDesc.ShareDisposition = IoDesc->ShareDisposition;
+
+                /* Let'se see if we can find a resource to satisfy this */
+                switch (IoDesc->Type)
+                {
+                    case CmResourceTypeInterrupt:
+                        /* Find an available interrupt */
+                        if (!IopFindInterruptResource(IoDesc, &NewDesc))
+                        {
+                            DPRINT1("Failed to find an available interrupt resource (0x%x to 0x%x)\n",
+                                    IoDesc->u.Interrupt.MinimumVector, IoDesc->u.Interrupt.MaximumVector);
+
+                            FoundResource = FALSE;
+                        }
+                        break;
+                        
+                    case CmResourceTypePort:
+                        /* Find an available port range */
+                        if (!IopFindPortResource(IoDesc, &NewDesc))
+                        {
+                            DPRINT1("Failed to find an available port resource (0x%I64x to 0x%I64x length: 0x%x)\n",
+                                    IoDesc->u.Port.MinimumAddress.QuadPart, IoDesc->u.Port.MaximumAddress.QuadPart,
+                                    IoDesc->u.Port.Length);
+
+                            FoundResource = FALSE;
+                        }
+                        break;
+                        
+                    case CmResourceTypeMemory:
+                        /* Find an available memory range */
+                        if (!IopFindMemoryResource(IoDesc, &NewDesc))
+                        {
+                            DPRINT1("Failed to find an available memory resource (0x%I64x to 0x%I64x length: 0x%x)\n",
+                                    IoDesc->u.Memory.MinimumAddress.QuadPart, IoDesc->u.Memory.MaximumAddress.QuadPart,
+                                    IoDesc->u.Memory.Length);
+
+                            FoundResource = FALSE;
+                        }
+                        break;
+                        
+                    case CmResourceTypeBusNumber:
+                        /* Find an available bus address range */
+                        if (!IopFindBusNumberResource(IoDesc, &NewDesc))
+                        {
+                            DPRINT1("Failed to find an available bus number resource (0x%x to 0x%x length: 0x%x)\n",
+                                    IoDesc->u.BusNumber.MinBusNumber, IoDesc->u.BusNumber.MaxBusNumber,
+                                    IoDesc->u.BusNumber.Length);
+
+                            FoundResource = FALSE;
+                        }
+                        break;
+                        
+                    case CmResourceTypeDma:
+                        /* Find an available DMA channel */
+                        if (!IopFindDmaResource(IoDesc, &NewDesc))
+                        {
+                            DPRINT1("Failed to find an available dma resource (0x%x to 0x%x)\n",
+                                    IoDesc->u.Dma.MinimumChannel, IoDesc->u.Dma.MaximumChannel);
+
+                            FoundResource = FALSE;
+                        }
+                        break;
+                        
+                    default:
+                        DPRINT1("Unsupported resource type: %x\n", IoDesc->Type);
+                        FoundResource = FALSE;
+                        break;
+                }
+
+                /* Check if it's missing and required */
+                if (!FoundResource && IoDesc->Option == 0)
+                {
+                    if (*ResourceList)
+                    {
+                        ExFreePool(*ResourceList);
+                        *ResourceList = NULL;
+                    }
+                    return STATUS_CONFLICTING_ADDRESSES;
+                }
+                else if (!FoundResource)
+                {
+                    /* Try an alternate for this preferred descriptor */
+                    AlternateRequired = TRUE;
+                    continue;
+                }
+                else
+                {
+                    /* Move on to the next preferred or required descriptor after this one */
+                    AlternateRequired = FALSE;
+                }
+
+                /* Figure out what we need */
+                if (PartialList == NULL)
+                {
+                    /* We need a new list */
+                    NewList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
+                    if (!NewList)
+                        return STATUS_NO_MEMORY;
+
+                    /* Set it up */
+                    NewList->Count = 1;
+                    NewList->List[0].InterfaceType = RequirementsList->InterfaceType;
+                    NewList->List[0].BusNumber = RequirementsList->BusNumber;
+                    NewList->List[0].PartialResourceList.Version = 1;
+                    NewList->List[0].PartialResourceList.Revision = 1;
+                    NewList->List[0].PartialResourceList.Count = 1;
+
+                    /* Set our pointer */
+                    DescPtr = &NewList->List[0].PartialResourceList.PartialDescriptors[0];
+                }
+                else
+                {
+                    /* Allocate the new larger list */
+                    NewList = ExAllocatePool(PagedPool, PnpDetermineResourceListSize(*ResourceList) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
+                    if (!NewList)
+                        return STATUS_NO_MEMORY;
+
+                    /* Copy the old stuff back */
+                    RtlCopyMemory(NewList, *ResourceList, PnpDetermineResourceListSize(*ResourceList));
+
+                    /* Set our pointer */
+                    DescPtr = &NewList->List[0].PartialResourceList.PartialDescriptors[NewList->List[0].PartialResourceList.Count];
+
+                    /* Increment the descriptor count */
+                    NewList->List[0].PartialResourceList.Count++;
+
+                    /* Free the old list */
+                    ExFreePool(*ResourceList);
+                }
+
+                /* Copy the descriptor in */
+                *DescPtr = NewDesc;
+
+                /* Store the new list */
+                *ResourceList = NewList;
+            }
+        }
+    }
 
-   return STATUS_SUCCESS;
+    /* Done */
+    return STATUS_SUCCESS;
 }
 
 static
@@ -357,7 +520,7 @@ IopCheckResourceDescriptor(
                  {
                       if (!Silent)
                       {
-                          DPRINT1("Resource conflict: Memory (0x%x to 0x%x vs. 0x%x to 0x%x)\n",
+                          DPRINT1("Resource conflict: Memory (0x%I64x to 0x%I64x vs. 0x%I64x to 0x%I64x)\n",
                                   ResDesc->u.Memory.Start.QuadPart, ResDesc->u.Memory.Start.QuadPart +
                                   ResDesc->u.Memory.Length, ResDesc2->u.Memory.Start.QuadPart,
                                   ResDesc2->u.Memory.Start.QuadPart + ResDesc2->u.Memory.Length);
@@ -378,7 +541,7 @@ IopCheckResourceDescriptor(
                  {
                       if (!Silent)
                       {
-                          DPRINT1("Resource conflict: Port (0x%x to 0x%x vs. 0x%x to 0x%x)\n",
+                          DPRINT1("Resource conflict: Port (0x%I64x to 0x%I64x vs. 0x%I64x to 0x%I64x)\n",
                                   ResDesc->u.Port.Start.QuadPart, ResDesc->u.Port.Start.QuadPart +
                                   ResDesc->u.Port.Length, ResDesc2->u.Port.Start.QuadPart,
                                   ResDesc2->u.Port.Start.QuadPart + ResDesc2->u.Port.Length);
@@ -509,7 +672,7 @@ IopUpdateControlKeyWithResources(IN PDEVICE_NODE DeviceNode)
    ZwClose(ControlKey);
 
    if (!NT_SUCCESS(Status))
-       return Status; 
+       return Status;
 
    return STATUS_SUCCESS;
 }
@@ -532,10 +695,10 @@ IopFilterResourceRequirements(IN PDEVICE_NODE DeviceNode)
       &Stack);
    if (!NT_SUCCESS(Status) && Status != STATUS_NOT_SUPPORTED)
    {
-      DPRINT("IopInitiatePnpIrp(IRP_MN_FILTER_RESOURCE_REQUIREMENTS) failed\n");
+      DPRINT1("IopInitiatePnpIrp(IRP_MN_FILTER_RESOURCE_REQUIREMENTS) failed\n");
       return Status;
    }
-   else if (NT_SUCCESS(Status))
+   else if (NT_SUCCESS(Status) && IoStatusBlock.Information)
    {
       DeviceNode->ResourceRequirements = (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information;
    }
@@ -632,7 +795,7 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2
           }
           
           NameU.Length = 0;
-          NameU.MaximumLength = OldLength + TranslatedSuffix.Length;
+          NameU.MaximumLength = (USHORT)OldLength + TranslatedSuffix.Length;
           
           Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
                                        DevicePropertyPhysicalDeviceObjectName,
@@ -658,7 +821,7 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2
           ASSERT(FALSE);
       }
       
-      NameU.Length = OldLength;
+      NameU.Length = (USHORT)OldLength;
 
       RtlAppendUnicodeStringToString(&NameU, &RawSuffix);
 
@@ -676,7 +839,7 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2
       }
 
       /* "Remove" the suffix by setting the length back to what it used to be */
-      NameU.Length = OldLength;
+      NameU.Length = (USHORT)OldLength;
 
       RtlAppendUnicodeStringToString(&NameU, &TranslatedSuffix);
 
@@ -758,6 +921,16 @@ IopTranslateDeviceResources(
                   DPRINT1("Failed to translate port resource (Start: 0x%I64x)\n", DescriptorRaw->u.Port.Start.QuadPart);
                   goto cleanup;
                }
+                
+               if (AddressSpace == 0)
+               {
+                   DPRINT1("Guessed incorrect address space: 1 -> 0\n");
+
+                   /* FIXME: I think all other CM_RESOURCE_PORT_XXX flags are 
+                    * invalid for this state but I'm not 100% sure */
+                   DescriptorRaw->Flags =
+                   DescriptorTranslated->Flags = CM_RESOURCE_PORT_MEMORY;
+               }
                break;
             }
             case CmResourceTypeInterrupt:
@@ -790,9 +963,17 @@ IopTranslateDeviceResources(
                   &DescriptorTranslated->u.Memory.Start))
                {
                   Status = STATUS_UNSUCCESSFUL;
-                  DPRINT1("Failed to translate memory resource (Start: 0xI64x)\n", DescriptorRaw->u.Memory.Start.QuadPart);
+                  DPRINT1("Failed to translate memory resource (Start: 0x%I64x)\n", DescriptorRaw->u.Memory.Start.QuadPart);
                   goto cleanup;
                }
+
+               if (AddressSpace != 0)
+               {
+                   DPRINT1("Guessed incorrect address space: 0 -> 1\n");
+
+                   /* This should never happen for memory space */
+                   ASSERT(FALSE);
+               }
             }
 
             case CmResourceTypeDma:
@@ -848,50 +1029,50 @@ IopAssignDeviceResources(
       return STATUS_SUCCESS;
    }
 
-   /* Fill DeviceNode->ResourceList
-    * FIXME: the PnP arbiter should go there!
-    * Actually, use the BootResources if provided, else the resource requirements
-    */
-
    if (DeviceNode->BootResources)
    {
-      ListSize = PnpDetermineResourceListSize(DeviceNode->BootResources);
-
-      DeviceNode->ResourceList = ExAllocatePool(PagedPool, ListSize);
-      if (!DeviceNode->ResourceList)
-      {
-         Status = STATUS_NO_MEMORY;
-         goto ByeBye;
-      }
-      RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, ListSize);
+       ListSize = PnpDetermineResourceListSize(DeviceNode->BootResources);
+
+       DeviceNode->ResourceList = ExAllocatePool(PagedPool, ListSize);
+       if (!DeviceNode->ResourceList)
+       {
+           Status = STATUS_NO_MEMORY;
+           goto ByeBye;
+       }
+
+       RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, ListSize);
+
+       Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL);
+       if (!NT_SUCCESS(Status))
+       {
+           DPRINT1("Boot resources for %wZ cause a resource conflict!\n", &DeviceNode->InstancePath);
+           ExFreePool(DeviceNode->ResourceList);
+           DeviceNode->ResourceList = NULL;
+       }
+   }
+   else
+   {
+       /* We'll make this from the requirements */
+       DeviceNode->ResourceList = NULL;
+   }
 
-      Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL);
-      if (NT_SUCCESS(Status) || !DeviceNode->ResourceRequirements)
-      {
-          if (!NT_SUCCESS(Status) && !DeviceNode->ResourceRequirements)
-          {
-              DPRINT1("Using conflicting boot resources because no requirements were supplied!\n");
-          }
+   /* No resources requirements */
+   if (!DeviceNode->ResourceRequirements)
+       goto Finish;
 
-          goto Finish;
-      }
-      else
-      {
-          DPRINT1("Boot resources for %wZ cause a resource conflict!\n", &DeviceNode->InstancePath);
-          ExFreePool(DeviceNode->ResourceList);
-          DeviceNode->ResourceList = NULL;
-      }
-   }
+   /* Call HAL to fixup our resource requirements list */
+   HalAdjustResourceList(&DeviceNode->ResourceRequirements);
 
-   Status = IopCreateResourceListFromRequirements(DeviceNode->ResourceRequirements,
-                                                  &DeviceNode->ResourceList);
+   /* Add resource requirements that aren't in the list we already got */
+   Status = IopFixupResourceListWithRequirements(DeviceNode->ResourceRequirements,
+                                                 &DeviceNode->ResourceList);
    if (!NT_SUCCESS(Status))
    {
-       DPRINT1("Failed to create a resource list from supplied resources for %wZ\n", &DeviceNode->InstancePath);
+       DPRINT1("Failed to fixup a resource list from supplied resources for %wZ\n", &DeviceNode->InstancePath);
        goto ByeBye;
    }
 
-   /* IopCreateResourceListFromRequirements should NEVER succeed with a conflicting list */
+   /* IopFixupResourceListWithRequirements should NEVER give us a conflicting list */
    ASSERT(IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL) != STATUS_CONFLICTING_ADDRESSES);
 
 Finish:
@@ -956,7 +1137,6 @@ IopCheckForResourceConflict(
       }
    }
 
-        
 ByeBye:
 
    return Result;
@@ -1007,7 +1187,7 @@ IopDetectResourceConflict(
               goto cleanup;
           }
 
-          Status = ZwEnumerateKey(ResourceMapKey, 
+          Status = ZwEnumerateKey(ResourceMapKey,
                                   ChildKeyIndex1,
                                   KeyBasicInformation,
                                   KeyInformation,
@@ -1021,7 +1201,7 @@ IopDetectResourceConflict(
           goto cleanup;
 
       KeyName.Buffer = KeyInformation->Name;
-      KeyName.MaximumLength = KeyName.Length = KeyInformation->NameLength;
+      KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength;
       InitializeObjectAttributes(&ObjectAttributes,
                                  &KeyName,
                                  OBJ_CASE_INSENSITIVE,
@@ -1034,7 +1214,7 @@ IopDetectResourceConflict(
 
       while (TRUE)
       {
-          Status = ZwEnumerateKey(ChildKey2, 
+          Status = ZwEnumerateKey(ChildKey2,
                                   ChildKeyIndex2,
                                   KeyBasicInformation,
                                   NULL,
@@ -1066,7 +1246,7 @@ IopDetectResourceConflict(
               goto cleanup;
 
           KeyName.Buffer = KeyInformation->Name;
-          KeyName.MaximumLength = KeyName.Length = KeyInformation->NameLength;
+          KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength;
           InitializeObjectAttributes(&ObjectAttributes,
                                      &KeyName,
                                      OBJ_CASE_INSENSITIVE,