Author: cgutman
Date: Sun Apr 4 03:18:41 2010
New Revision: 46708
URL:
http://svn.reactos.org/svn/reactos?rev=46708&view=rev
Log:
[NTOSKRNL]
- Revert part of r46707
- Remove a hack in PnpRoot that assembled a CM_RESOURCE_LIST from a
CM_PARTIAL_RESOURCE_DESCRIPTOR but also corrupted proper resource lists (such as from
detected devices in IoReportDetectedDevice)
- Add a simple resource arbiter that finds an unused resource in the range provided in the
resource requirements list. It's not perfect but it's a start.
- Start enforcing resource conflicts
- Fix incorrect code that was writing a CM_PARTIAL_RESOURCE_DESCRIPTOR instead of a
CM_RESOURCE_LIST (the hack above was compensating for this) which result in BootConfig
being a REG_PARTIAL_RESOURCE_DESCRIPTOR type on certain devices and a REG_RESOURCE_LIST on
others
- Fix a broken check for no partial resource descriptors
Modified:
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Sun Apr 4 03:18:41 2010
@@ -1005,137 +1005,183 @@
}
BOOLEAN
+IopCheckResourceDescriptor(
+ IN PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc,
+ IN PCM_RESOURCE_LIST ResourceList,
+ IN BOOLEAN Silent,
+ OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
+{
+ ULONG i, ii;
+ BOOLEAN Result = FALSE;
+
+ if (ResDesc->ShareDisposition == CmResourceShareShared)
+ return FALSE;
+
+ for (i = 0; i < ResourceList->Count; i++)
+ {
+ PCM_PARTIAL_RESOURCE_LIST ResList =
&ResourceList->List[i].PartialResourceList;
+ for (ii = 0; ii < ResList->Count; ii++)
+ {
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc2 =
&ResList->PartialDescriptors[ii];
+
+ /* We don't care about shared resources */
+ if (ResDesc->ShareDisposition == CmResourceShareShared &&
+ ResDesc2->ShareDisposition == CmResourceShareShared)
+ continue;
+
+ /* Make sure we're comparing the same types */
+ if (ResDesc->Type != ResDesc2->Type)
+ continue;
+
+ switch (ResDesc->Type)
+ {
+ case CmResourceTypeMemory:
+ if ((ResDesc->u.Memory.Start.QuadPart <
ResDesc2->u.Memory.Start.QuadPart &&
+ ResDesc->u.Memory.Start.QuadPart + ResDesc->u.Memory.Length
>
+ ResDesc2->u.Memory.Start.QuadPart) ||
(ResDesc2->u.Memory.Start.QuadPart <
+ ResDesc->u.Memory.Start.QuadPart &&
ResDesc2->u.Memory.Start.QuadPart +
+ ResDesc2->u.Memory.Length >
ResDesc->u.Memory.Start.QuadPart))
+ {
+ if (!Silent)
+ {
+ DPRINT1("Resource conflict: Memory (0x%x to 0x%x vs. 0x%x
to 0x%x)\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);
+ }
+
+ Result = TRUE;
+
+ goto ByeBye;
+ }
+ break;
+
+ case CmResourceTypePort:
+ if ((ResDesc->u.Port.Start.QuadPart <
ResDesc2->u.Port.Start.QuadPart &&
+ ResDesc->u.Port.Start.QuadPart + ResDesc->u.Port.Length >
+ ResDesc2->u.Port.Start.QuadPart) ||
(ResDesc2->u.Port.Start.QuadPart <
+ ResDesc->u.Port.Start.QuadPart &&
ResDesc2->u.Port.Start.QuadPart +
+ ResDesc2->u.Port.Length >
ResDesc->u.Port.Start.QuadPart))
+ {
+ if (!Silent)
+ {
+ DPRINT1("Resource conflict: Port (0x%x to 0x%x vs. 0x%x to
0x%x)\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);
+ }
+
+ Result = TRUE;
+
+ goto ByeBye;
+ }
+ break;
+
+ case CmResourceTypeInterrupt:
+ if (ResDesc->u.Interrupt.Vector == ResDesc2->u.Interrupt.Vector)
+ {
+ if (!Silent)
+ {
+ DPRINT1("Resource conflict: IRQ (0x%x 0x%x vs. 0x%x
0x%x)\n",
+ ResDesc->u.Interrupt.Vector,
ResDesc->u.Interrupt.Level,
+ ResDesc2->u.Interrupt.Vector,
ResDesc2->u.Interrupt.Level);
+ }
+
+ Result = TRUE;
+
+ goto ByeBye;
+ }
+ break;
+
+ case CmResourceTypeBusNumber:
+ if ((ResDesc->u.BusNumber.Start < ResDesc2->u.BusNumber.Start
&&
+ ResDesc->u.BusNumber.Start + ResDesc->u.BusNumber.Length
>
+ ResDesc2->u.BusNumber.Start) || (ResDesc2->u.BusNumber.Start
<
+ ResDesc->u.BusNumber.Start &&
ResDesc2->u.BusNumber.Start +
+ ResDesc2->u.BusNumber.Length >
ResDesc->u.BusNumber.Start))
+ {
+ if (!Silent)
+ {
+ DPRINT1("Resource conflict: Bus number (0x%x to 0x%x vs.
0x%x to 0x%x)\n",
+ ResDesc->u.BusNumber.Start,
ResDesc->u.BusNumber.Start +
+ ResDesc->u.BusNumber.Length,
ResDesc2->u.BusNumber.Start,
+ ResDesc2->u.BusNumber.Start +
ResDesc2->u.BusNumber.Length);
+ }
+
+ Result = TRUE;
+
+ goto ByeBye;
+ }
+ break;
+
+ case CmResourceTypeDma:
+ if (ResDesc->u.Dma.Channel == ResDesc2->u.Dma.Channel)
+ {
+ if (!Silent)
+ {
+ DPRINT1("Resource conflict: Dma (0x%x 0x%x vs. 0x%x
0x%x)\n",
+ ResDesc->u.Dma.Channel, ResDesc->u.Dma.Port,
+ ResDesc2->u.Dma.Channel, ResDesc2->u.Dma.Port);
+ }
+
+ Result = TRUE;
+
+ goto ByeBye;
+ }
+ break;
+ }
+ }
+ }
+
+ByeBye:
+
+ if (Result && ConflictingDescriptor)
+ {
+ RtlCopyMemory(ConflictingDescriptor,
+ ResDesc,
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
+ }
+
+ return Result;
+}
+
+
+BOOLEAN
IopCheckForResourceConflict(
IN PCM_RESOURCE_LIST ResourceList1,
- IN PCM_RESOURCE_LIST ResourceList2)
-{
- ULONG i1, i2, ii1, ii2;
+ IN PCM_RESOURCE_LIST ResourceList2,
+ IN BOOLEAN Silent,
+ OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
+{
+ ULONG i, ii;
BOOLEAN Result = FALSE;
- for (i1 = 0; i1 < ResourceList1->Count; i1++)
- {
- PCM_PARTIAL_RESOURCE_LIST ResList1 =
&ResourceList1->List[i1].PartialResourceList;
- for (i2 = 0; i2 < ResourceList2->Count; i2++)
- {
- PCM_PARTIAL_RESOURCE_LIST ResList2 =
&ResourceList2->List[i2].PartialResourceList;
- for (ii1 = 0; ii1 < ResList1->Count; ii1++)
- {
- PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc1 =
&ResList1->PartialDescriptors[ii1];
-
- if (ResDesc1->ShareDisposition == CmResourceShareShared)
- continue;
-
- for (ii2 = 0; ii2 < ResList2->Count; ii2++)
- {
- PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc2 =
&ResList2->PartialDescriptors[ii2];
-
- /* We don't care about shared resources */
- if (ResDesc2->ShareDisposition == CmResourceShareShared)
- continue;
-
- /* Make sure we're comparing the same types */
- if (ResDesc1->Type != ResDesc2->Type)
- continue;
-
- switch (ResDesc1->Type)
- {
- case CmResourceTypeMemory:
- if ((ResDesc1->u.Memory.Start.QuadPart <
ResDesc2->u.Memory.Start.QuadPart &&
- ResDesc1->u.Memory.Start.QuadPart +
ResDesc1->u.Memory.Length >
- ResDesc2->u.Memory.Start.QuadPart) ||
(ResDesc2->u.Memory.Start.QuadPart <
- ResDesc1->u.Memory.Start.QuadPart &&
ResDesc2->u.Memory.Start.QuadPart +
- ResDesc2->u.Memory.Length >
ResDesc1->u.Memory.Start.QuadPart))
- {
- DPRINT1("Resource conflict: Memory (0x%x to 0x%x vs. 0x%x
to 0x%x)\n",
- ResDesc1->u.Memory.Start.QuadPart,
ResDesc1->u.Memory.Start.QuadPart +
- ResDesc1->u.Memory.Length,
ResDesc2->u.Memory.Start.QuadPart,
- ResDesc2->u.Memory.Start.QuadPart +
ResDesc2->u.Memory.Length);
-
- Result = TRUE;
-
- goto ByeBye;
- }
- break;
-
- case CmResourceTypePort:
- if ((ResDesc1->u.Port.Start.QuadPart <
ResDesc2->u.Port.Start.QuadPart &&
- ResDesc1->u.Port.Start.QuadPart +
ResDesc1->u.Port.Length >
- ResDesc2->u.Port.Start.QuadPart) ||
(ResDesc2->u.Port.Start.QuadPart <
- ResDesc1->u.Port.Start.QuadPart &&
ResDesc2->u.Port.Start.QuadPart +
- ResDesc2->u.Port.Length >
ResDesc1->u.Port.Start.QuadPart))
- {
- DPRINT1("Resource conflict: Port (0x%x to 0x%x vs. 0x%x to
0x%x)\n",
- ResDesc1->u.Port.Start.QuadPart,
ResDesc1->u.Port.Start.QuadPart +
- ResDesc1->u.Port.Length,
ResDesc2->u.Port.Start.QuadPart,
- ResDesc2->u.Port.Start.QuadPart +
ResDesc2->u.Port.Length);
-
- Result = TRUE;
-
- goto ByeBye;
- }
- break;
-
- case CmResourceTypeInterrupt:
- if (ResDesc1->u.Interrupt.Vector ==
ResDesc2->u.Interrupt.Vector)
- {
- DPRINT1("Resource conflict: IRQ (0x%x 0x%x vs. 0x%x
0x%x)\n",
- ResDesc1->u.Interrupt.Vector,
ResDesc1->u.Interrupt.Level,
- ResDesc2->u.Interrupt.Vector,
ResDesc2->u.Interrupt.Level);
-
- Result = TRUE;
-
- goto ByeBye;
- }
- break;
-
- case CmResourceTypeBusNumber:
- if ((ResDesc1->u.BusNumber.Start <
ResDesc2->u.BusNumber.Start &&
- ResDesc1->u.BusNumber.Start +
ResDesc1->u.BusNumber.Length >
- ResDesc2->u.BusNumber.Start) ||
(ResDesc2->u.BusNumber.Start <
- ResDesc1->u.BusNumber.Start &&
ResDesc2->u.BusNumber.Start +
- ResDesc2->u.BusNumber.Length >
ResDesc1->u.BusNumber.Start))
- {
- DPRINT1("Resource conflict: Bus number (0x%x to 0x%x vs.
0x%x to 0x%x)\n",
- ResDesc1->u.BusNumber.Start,
ResDesc1->u.BusNumber.Start +
- ResDesc1->u.BusNumber.Length,
ResDesc2->u.BusNumber.Start,
- ResDesc2->u.BusNumber.Start +
ResDesc2->u.BusNumber.Length);
-
- Result = TRUE;
-
- goto ByeBye;
- }
- break;
-
- case CmResourceTypeDma:
- if (ResDesc1->u.Dma.Channel == ResDesc2->u.Dma.Channel)
- {
- DPRINT1("Resource conflict: Dma (0x%x 0x%x vs. 0x%x
0x%x)\n",
- ResDesc1->u.Dma.Channel, ResDesc1->u.Dma.Port,
- ResDesc2->u.Dma.Channel, ResDesc2->u.Dma.Port);
-
- Result = TRUE;
-
- goto ByeBye;
- }
- break;
- }
- }
- }
- }
- }
-
+ for (i = 0; i < ResourceList1->Count; i++)
+ {
+ PCM_PARTIAL_RESOURCE_LIST ResList =
&ResourceList1->List[i].PartialResourceList;
+ for (ii = 0; ii < ResList->Count; ii++)
+ {
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc =
&ResList->PartialDescriptors[ii];
+
+ Result = IopCheckResourceDescriptor(ResDesc,
+ ResourceList2,
+ Silent,
+ ConflictingDescriptor);
+ if (Result) goto ByeBye;
+ }
+ }
+
+
ByeBye:
-#ifdef ENABLE_RESOURCE_CONFLICT_DETECTION
return Result;
-#else
- return FALSE;
-#endif
}
NTSTATUS
IopDetectResourceConflict(
- IN PCM_RESOURCE_LIST ResourceList)
+ IN PCM_RESOURCE_LIST ResourceList,
+ IN BOOLEAN Silent,
+ OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
@@ -1321,7 +1367,9 @@
ExFreePool(KeyNameInformation);
if (IopCheckForResourceConflict(ResourceList,
-
(PCM_RESOURCE_LIST)KeyValueInformation->Data))
+
(PCM_RESOURCE_LIST)KeyValueInformation->Data,
+ Silent,
+ ConflictingDescriptor))
{
ExFreePool(KeyValueInformation);
Status = STATUS_CONFLICTING_ADDRESSES;
@@ -1346,19 +1394,312 @@
return Status;
}
-
+
+BOOLEAN
+IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL
PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
+{
+ CM_RESOURCE_LIST CmList;
+ NTSTATUS Status;
+
+ CmList.Count = 1;
+ CmList.List[0].InterfaceType = InterfaceTypeUndefined;
+ CmList.List[0].BusNumber = 0;
+ CmList.List[0].PartialResourceList.Version = 1;
+ CmList.List[0].PartialResourceList.Revision = 1;
+ CmList.List[0].PartialResourceList.Count = 1;
+ CmList.List[0].PartialResourceList.PartialDescriptors[0] = *CmDesc;
+
+ Status = IopDetectResourceConflict(&CmList, TRUE, ConflictingDescriptor);
+ if (Status == STATUS_CONFLICTING_ADDRESSES)
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOLEAN
+IopFindBusNumberResource(
+ IN PIO_RESOURCE_DESCRIPTOR IoDesc,
+ OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
+{
+ ULONG Start;
+ CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
+
+ ASSERT(IoDesc->Type == CmDesc->Type);
+ ASSERT(IoDesc->Type == CmResourceTypeBusNumber);
+
+ for (Start = IoDesc->u.BusNumber.MinBusNumber;
+ Start < IoDesc->u.BusNumber.MaxBusNumber;
+ Start++)
+ {
+ CmDesc->u.BusNumber.Length = IoDesc->u.BusNumber.Length;
+ CmDesc->u.BusNumber.Start = Start;
+
+ if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc))
+ {
+ Start += ConflictingDesc.u.BusNumber.Start +
ConflictingDesc.u.BusNumber.Length;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+IopFindMemoryResource(
+ IN PIO_RESOURCE_DESCRIPTOR IoDesc,
+ OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
+{
+ ULONGLONG Start;
+ CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
+
+ ASSERT(IoDesc->Type == CmDesc->Type);
+ ASSERT(IoDesc->Type == CmResourceTypeMemory);
+
+ for (Start = IoDesc->u.Memory.MinimumAddress.QuadPart;
+ Start < IoDesc->u.Memory.MaximumAddress.QuadPart;
+ Start++)
+ {
+ 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;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+IopFindPortResource(
+ IN PIO_RESOURCE_DESCRIPTOR IoDesc,
+ OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
+{
+ ULONGLONG Start;
+ CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
+
+ ASSERT(IoDesc->Type == CmDesc->Type);
+ ASSERT(IoDesc->Type == CmResourceTypePort);
+
+ for (Start = IoDesc->u.Port.MinimumAddress.QuadPart;
+ Start < IoDesc->u.Port.MaximumAddress.QuadPart;
+ Start++)
+ {
+ CmDesc->u.Port.Length = IoDesc->u.Port.Length;
+ CmDesc->u.Port.Start.QuadPart = Start;
+
+ if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc))
+ {
+ Start += ConflictingDesc.u.Port.Start.QuadPart +
ConflictingDesc.u.Port.Length;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+IopFindDmaResource(
+ IN PIO_RESOURCE_DESCRIPTOR IoDesc,
+ OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
+{
+ ULONG Channel;
+
+ ASSERT(IoDesc->Type == CmDesc->Type);
+ ASSERT(IoDesc->Type == CmResourceTypeDma);
+
+ for (Channel = IoDesc->u.Dma.MinimumChannel;
+ Channel < IoDesc->u.Dma.MaximumChannel;
+ Channel++)
+ {
+ CmDesc->u.Dma.Channel = Channel;
+ CmDesc->u.Dma.Port = 0;
+
+ if (!IopCheckDescriptorForConflict(CmDesc, NULL))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+IopFindInterruptResource(
+ IN PIO_RESOURCE_DESCRIPTOR IoDesc,
+ OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
+{
+ ULONG Vector;
+
+ ASSERT(IoDesc->Type == CmDesc->Type);
+ ASSERT(IoDesc->Type == CmResourceTypeInterrupt);
+
+ for (Vector = IoDesc->u.Interrupt.MinimumVector;
+ Vector < IoDesc->u.Interrupt.MaximumVector;
+ Vector++)
+ {
+ CmDesc->u.Interrupt.Vector = Vector;
+ CmDesc->u.Interrupt.Level = Vector;
+ CmDesc->u.Interrupt.Affinity = (KAFFINITY)-1;
+
+ if (!IopCheckDescriptorForConflict(CmDesc, NULL))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+NTSTATUS
+IopCreateResourceListFromRequirements(
+ 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);
+ }
+
+ DPRINT1("Allocating resource list: %d\n", Size);
+ *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);
+ 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);
+ 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);
+ 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);
+ 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);
+
+ if (ReqDesc->Option == 0)
+ {
+ ExFreePool(*ResourceList);
+ return STATUS_CONFLICTING_ADDRESSES;
+ }
+ }
+ break;
+
+ default:
+ DPRINT1("Unsupported resource type: %x\n", ReqDesc->Type);
+ break;
+ }
+
+ (*ResourceList)->List[0].PartialResourceList.Count++;
+ ResDesc++;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
IopAssignDeviceResources(
IN PDEVICE_NODE DeviceNode,
OUT ULONG *pRequiredSize)
{
- PIO_RESOURCE_LIST ResourceList;
- PIO_RESOURCE_DESCRIPTOR ResourceDescriptor;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw;
PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
- ULONG NumberOfResources = 0;
ULONG Size;
- ULONG i, j;
+ ULONG i;
+ ULONG j;
NTSTATUS Status;
if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements)
@@ -1371,7 +1712,7 @@
/* Fill DeviceNode->ResourceList
* FIXME: the PnP arbiter should go there!
- * Actually, use the BootResources if provided, else the resource list #0
+ * Actually, use the BootResources if provided, else the resource requirements
*/
if (DeviceNode->BootResources)
@@ -1398,161 +1739,38 @@
}
RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, Size);
- Status = IopDetectResourceConflict(DeviceNode->ResourceList);
- if (!NT_SUCCESS(Status))
- goto ByeBye;
-
- *pRequiredSize = Size;
- return STATUS_SUCCESS;
- }
-
- /* Ok, here, we have to use the device requirement list */
- ResourceList = &DeviceNode->ResourceRequirements->List[0];
- if (ResourceList->Version != 1 || ResourceList->Revision != 1)
- {
- Status = STATUS_REVISION_MISMATCH;
- goto ByeBye;
- }
-
- Size = sizeof(CM_RESOURCE_LIST) + ResourceList->Count *
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
- DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size);
- if (!DeviceNode->ResourceList)
- {
- Status = STATUS_NO_MEMORY;
- goto ByeBye;
- }
-
- DeviceNode->ResourceList->Count = 1;
- DeviceNode->ResourceList->List[0].InterfaceType =
DeviceNode->ResourceRequirements->InterfaceType;
- DeviceNode->ResourceList->List[0].BusNumber =
DeviceNode->ResourceRequirements->BusNumber;
- DeviceNode->ResourceList->List[0].PartialResourceList.Version = 1;
- DeviceNode->ResourceList->List[0].PartialResourceList.Revision = 1;
-
- for (i = 0; i < ResourceList->Count; i++)
- {
- ResourceDescriptor = &ResourceList->Descriptors[i];
-
- if (ResourceDescriptor->Option == 0 || ResourceDescriptor->Option ==
IO_RESOURCE_PREFERRED)
- {
- DescriptorRaw =
&DeviceNode->ResourceList->List[0].PartialResourceList.PartialDescriptors[NumberOfResources];
- NumberOfResources++;
-
- /* Copy ResourceDescriptor to DescriptorRaw and DescriptorTranslated */
- DescriptorRaw->Type = ResourceDescriptor->Type;
- DescriptorRaw->ShareDisposition = ResourceDescriptor->ShareDisposition;
- DescriptorRaw->Flags = ResourceDescriptor->Flags;
- switch (ResourceDescriptor->Type)
- {
- case CmResourceTypePort:
- {
- DescriptorRaw->u.Port.Start =
ResourceDescriptor->u.Port.MinimumAddress;
- DescriptorRaw->u.Port.Length = ResourceDescriptor->u.Port.Length;
- break;
- }
- case CmResourceTypeInterrupt:
- {
- INTERFACE_TYPE BusType;
- ULONG SlotNumber;
- ULONG ret;
- UCHAR Irq;
-
- DescriptorRaw->u.Interrupt.Level = 0;
- DescriptorRaw->u.Interrupt.Vector =
ResourceDescriptor->u.Interrupt.MinimumVector;
- /* FIXME: HACK: if we have a PCI device, we try
- * to keep the IRQ assigned by the BIOS */
- if (NT_SUCCESS(IoGetDeviceProperty(
- DeviceNode->PhysicalDeviceObject,
- DevicePropertyLegacyBusType,
- sizeof(INTERFACE_TYPE),
- &BusType,
- &ret)) && BusType == PCIBus)
- {
- /* We have a PCI bus */
- if (NT_SUCCESS(IoGetDeviceProperty(
- DeviceNode->PhysicalDeviceObject,
- DevicePropertyAddress,
- sizeof(ULONG),
- &SlotNumber,
- &ret)) && SlotNumber > 0)
- {
- /* We have a good slot number */
- ret = HalGetBusDataByOffset(PCIConfiguration,
-
DeviceNode->ResourceRequirements->BusNumber,
- SlotNumber,
- &Irq,
- 0x3c /* PCI_INTERRUPT_LINE */,
- sizeof(UCHAR));
- if (ret != 0 && ret != 2
- && ResourceDescriptor->u.Interrupt.MinimumVector
<= Irq
- && ResourceDescriptor->u.Interrupt.MaximumVector
>= Irq)
- {
- /* The device already has an assigned IRQ */
- DescriptorRaw->u.Interrupt.Vector = Irq;
- }
- else
- {
- DPRINT1("Trying to assign IRQ 0x%lx to %wZ\n",
- DescriptorRaw->u.Interrupt.Vector,
- &DeviceNode->InstancePath);
- Irq = (UCHAR)DescriptorRaw->u.Interrupt.Vector;
- ret = HalSetBusDataByOffset(PCIConfiguration,
- DeviceNode->ResourceRequirements->BusNumber,
- SlotNumber,
- &Irq,
- 0x3c /* PCI_INTERRUPT_LINE */,
- sizeof(UCHAR));
- if (ret == 0 || ret == 2)
- ASSERT(FALSE);
- }
- }
- }
- break;
- }
- case CmResourceTypeMemory:
- {
- DescriptorRaw->u.Memory.Start =
ResourceDescriptor->u.Memory.MinimumAddress;
- DescriptorRaw->u.Memory.Length =
ResourceDescriptor->u.Memory.Length;
- break;
- }
- case CmResourceTypeDma:
- {
- DescriptorRaw->u.Dma.Channel =
ResourceDescriptor->u.Dma.MinimumChannel;
- DescriptorRaw->u.Dma.Port = 0; /* FIXME */
- DescriptorRaw->u.Dma.Reserved1 = 0;
- break;
- }
- case CmResourceTypeBusNumber:
- {
- DescriptorRaw->u.BusNumber.Start =
ResourceDescriptor->u.BusNumber.MinBusNumber;
- DescriptorRaw->u.BusNumber.Length =
ResourceDescriptor->u.BusNumber.Length;
- DescriptorRaw->u.BusNumber.Reserved =
ResourceDescriptor->u.BusNumber.Reserved;
- break;
- }
- /*CmResourceTypeDevicePrivate:
- case CmResourceTypePcCardConfig:
- case CmResourceTypeMfCardConfig:
- {
- RtlCopyMemory(
- &DescriptorRaw->u.DevicePrivate,
- &ResourceDescriptor->u.DevicePrivate,
- sizeof(ResourceDescriptor->u.DevicePrivate));
- RtlCopyMemory(
- &DescriptorTranslated->u.DevicePrivate,
- &ResourceDescriptor->u.DevicePrivate,
- sizeof(ResourceDescriptor->u.DevicePrivate));
- break;
- }*/
- default:
- DPRINT1("IopAssignDeviceResources(): unknown resource descriptor type
0x%x\n", ResourceDescriptor->Type);
- NumberOfResources--;
- }
- }
-
- }
-
- DeviceNode->ResourceList->List[0].PartialResourceList.Count =
NumberOfResources;
-
- Status = IopDetectResourceConflict(DeviceNode->ResourceList);
+ 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");
+ }
+
+ *pRequiredSize = Size;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ DPRINT1("Boot resources for %wZ cause a resource conflict!\n",
&DeviceNode->InstancePath);
+ ExFreePool(DeviceNode->ResourceList);
+ }
+ }
+
+ Status = IopCreateResourceListFromRequirements(DeviceNode->ResourceRequirements,
+ &DeviceNode->ResourceList);
+ if (!NT_SUCCESS(Status))
+ goto ByeBye;
+
+ Size = FIELD_OFFSET(CM_RESOURCE_LIST, List);
+ for (i = 0; i < DeviceNode->ResourceList->Count; i++)
+ {
+ pPartialResourceList =
&DeviceNode->ResourceList->List[i].PartialResourceList;
+ Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR,
PartialResourceList.PartialDescriptors)
+ + pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+ }
+
+ Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL);
if (!NT_SUCCESS(Status))
goto ByeBye;
@@ -2744,6 +2962,8 @@
PUNICODE_STRING pHardwareId;
ULONG DeviceIndex = 0;
BOOLEAN IsDeviceDesc;
+ PUCHAR CmResourceList;
+ ULONG ListCount;
if (RelativePath)
{
@@ -2858,7 +3078,7 @@
DPRINT("ExAllocatePool() failed\n");
goto nextdevice;
}
- if (ParentBootResourcesLength == 0)
+ if (ParentBootResourcesLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
{
RtlCopyMemory(BootResources, pValueInformation->Data,
pValueInformation->DataLength);
}
@@ -3094,10 +3314,29 @@
ZwDeleteKey(hLevel2Key);
goto nextdevice;
}
- if (BootResourcesLength > 0)
- {
+ if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
+ {
+ CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength +
sizeof(ULONG));
+ if (!CmResourceList)
+ {
+ ZwClose(hLogConf);
+ ZwDeleteKey(hLevel2Key);
+ goto nextdevice;
+ }
+
+ /* Add the list count (1st member of CM_RESOURCE_LIST) */
+ ListCount = 1;
+ RtlCopyMemory(CmResourceList,
+ &ListCount,
+ sizeof(ULONG));
+
+ /* Now add the actual list (2nd member of CM_RESOURCE_LIST) */
+ RtlCopyMemory(CmResourceList + sizeof(ULONG),
+ BootResources,
+ BootResourcesLength);
+
/* Save boot resources to 'LogConf\BootConfig' */
- Status = ZwSetValueKey(hLogConf, &BootConfigU, 0,
REG_FULL_RESOURCE_DESCRIPTOR, BootResources, BootResourcesLength);
+ Status = ZwSetValueKey(hLogConf, &BootConfigU, 0,
REG_FULL_RESOURCE_DESCRIPTOR, CmResourceList, BootResourcesLength + sizeof(ULONG));
if (!NT_SUCCESS(Status))
{
DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
@@ -3110,7 +3349,10 @@
nextdevice:
if (BootResources && BootResources != ParentBootResources)
+ {
ExFreePool(BootResources);
+ BootResources = NULL;
+ }
if (hLevel2Key)
{
ZwClose(hLevel2Key);
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnproot…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c [iso-8859-1] Sun Apr 4 03:18:41 2010
@@ -694,9 +694,13 @@
break;
}
- /* Pass this IRP down to the root device PDO */
- IoSkipCurrentIrpStackLocation(Irp);
- return IoCallDriver(DeviceExtension->Ldo, Irp);
+ if (Status != STATUS_PENDING)
+ {
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+
+ return Status;
}
static NTSTATUS
@@ -778,16 +782,16 @@
/* Copy existing resource requirement list */
ResourceList = ExAllocatePool(
PagedPool,
- FIELD_OFFSET(CM_RESOURCE_LIST, List) +
DeviceExtension->DeviceInfo->ResourceListSize);
+ DeviceExtension->DeviceInfo->ResourceListSize);
if (!ResourceList)
return STATUS_NO_MEMORY;
- ResourceList->Count = 1;
RtlCopyMemory(
- &ResourceList->List,
+ ResourceList,
DeviceExtension->DeviceInfo->ResourceList,
DeviceExtension->DeviceInfo->ResourceListSize);
- Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+
+ Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
}
return STATUS_SUCCESS;