···1335133513361336 /* TODO: Assign the other resources we get to the card */
1337133713381338- for (i = 0; i < RawResList->Count; i++)
13381338+ RawFullDesc = &RawResList->List[0];
13391339+ for (i = 0; i < RawResList->Count; i++, RawFullDesc = CmiGetNextResourceDescriptor(RawFullDesc))
13391340 {
13401340- RawFullDesc = &RawResList->List[i];
13411341-13421341 for (ii = 0; ii < RawFullDesc->PartialResourceList.Count; ii++)
13431342 {
13431343+ /* Partial resource descriptors can be of variable size (CmResourceTypeDeviceSpecific),
13441344+ but only one is allowed and it must be the last one in the list! */
13441345 RawPartialDesc = &RawFullDesc->PartialResourceList.PartialDescriptors[ii];
1345134613461347 if (RawPartialDesc->Type == CmResourceTypeInterrupt)
···386386 Count = FullDescriptor->PartialResourceList.Count;
387387 for (PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors;
388388 Count;
389389- PartialDescriptor = PciNextPartialDescriptor(PartialDescriptor))
389389+ PartialDescriptor = CmiGetNextPartialDescriptor(PartialDescriptor))
390390 {
391391 /* Print each partial */
392392 PciDebugPrintPartialResource(PartialDescriptor);
393393 Count--;
394394 }
395395+396396+ /* Go to the next full descriptor */
397397+ FullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)PartialDescriptor;
395398 }
396399397400 /* Done printing data */
+1-1
drivers/bus/pcix/enum.c
···168168 }
169169170170 /* Move to the next descriptor */
171171- Partial = PciNextPartialDescriptor(Partial);
171171+ Partial = CmiGetNextPartialDescriptor(Partial);
172172 }
173173174174 /* We should be starting a new list now */
+5-10
drivers/bus/pcix/pci.h
···1919#include <ndk/rtlfuncs.h>
2020#include <ndk/vffuncs.h>
2121#include <arbiter.h>
2222+#include <cmreslist.h>
22232324//
2425// Tag used in all pool allocations (Pci Bus)
···11731174 IN OUT PDEVICE_CAPABILITIES DeviceCapability
11741175);
1175117611761176-PCM_PARTIAL_RESOURCE_DESCRIPTOR
11771177-NTAPI
11781178-PciNextPartialDescriptor(
11791179- PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor
11801180-);
11811181-11821177//
11831178// Configuration Routines
11841179//
···17871782 IN PDEVICE_OBJECT DeviceObject,
17881783 IN ULONG BusNumber,
17891784 IN ULONG SlotNumber,
17901790- IN UCHAR InterruptLine,
17911791- IN UCHAR InterruptPin,
17921792- IN UCHAR BaseClass,
17931793- IN UCHAR SubClass,
17851785+ IN UCHAR InterruptLine,
17861786+ IN UCHAR InterruptPin,
17871787+ IN UCHAR BaseClass,
17881788+ IN UCHAR SubClass,
17941789 IN PDEVICE_OBJECT PhysicalDeviceObject,
17951790 IN PPCI_PDO_EXTENSION PdoExtension,
17961791 OUT PDEVICE_OBJECT *pFoundDeviceObject
-21
drivers/bus/pcix/utils.c
···17641764 return Status;
17651765}
1766176617671767-PCM_PARTIAL_RESOURCE_DESCRIPTOR
17681768-NTAPI
17691769-PciNextPartialDescriptor(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor)
17701770-{
17711771- PCM_PARTIAL_RESOURCE_DESCRIPTOR NextDescriptor;
17721772-17731773- /* Assume the descriptors are the fixed size ones */
17741774- NextDescriptor = CmDescriptor + 1;
17751775-17761776- /* But check if this is actually a variable-sized descriptor */
17771777- if (CmDescriptor->Type == CmResourceTypeDeviceSpecific)
17781778- {
17791779- /* Add the size of the variable section as well */
17801780- NextDescriptor = (PVOID)((ULONG_PTR)NextDescriptor +
17811781- CmDescriptor->u.DeviceSpecificData.DataSize);
17821782- }
17831783-17841784- /* Now the correct pointer has been computed, return it */
17851785- return NextDescriptor;
17861786-}
17871787-17881767/* EOF */
+1
ntoskrnl/include/internal/cm.h
···77 */
88#define _CM_
99#include "cmlib.h"
1010+#include <cmreslist.h>
10111112//
1213// Define this if you want debugging support
+51-9
ntoskrnl/io/pnpmgr/pnpres.c
···1212#define NDEBUG
1313#include <debug.h>
14141515+FORCEINLINE
1616+PIO_RESOURCE_LIST
1717+IopGetNextResourceList(
1818+ _In_ const IO_RESOURCE_LIST *ResourceList)
1919+{
2020+ ASSERT((ResourceList->Count > 0) && (ResourceList->Count < 1000));
2121+ return (PIO_RESOURCE_LIST)(
2222+ &ResourceList->Descriptors[ResourceList->Count]);
2323+}
2424+1525static
1626BOOLEAN
1727IopCheckDescriptorForConflict(
···199209 }
200210 }
201211212212+ DPRINT1("Failed to satisfy interrupt requirement with IRQ 0x%x-0x%x\n",
213213+ IoDesc->u.Interrupt.MinimumVector,
214214+ IoDesc->u.Interrupt.MaximumVector);
202215 return FALSE;
203216}
204217···209222{
210223 ULONG i, OldCount;
211224 BOOLEAN AlternateRequired = FALSE;
225225+ PIO_RESOURCE_LIST ResList;
212226213227 /* Save the initial resource count when we got here so we can restore if an alternate fails */
214228 if (*ResourceList != NULL)
···216230 else
217231 OldCount = 0;
218232219219- for (i = 0; i < RequirementsList->AlternativeLists; i++)
233233+ ResList = &RequirementsList->List[0];
234234+ for (i = 0; i < RequirementsList->AlternativeLists; i++, ResList = IopGetNextResourceList(ResList))
220235 {
221236 ULONG ii;
222222- PIO_RESOURCE_LIST ResList = &RequirementsList->List[i];
223237224238 /* We need to get back to where we were before processing the last alternative list */
225239 if (OldCount == 0 && *ResourceList != NULL)
···275289276290 for (iii = 0; PartialList && iii < PartialList->Count && !Matched; iii++)
277291 {
292292+ /* Partial resource descriptors can be of variable size (CmResourceTypeDeviceSpecific),
293293+ but only one is allowed and it must be the last one in the list! */
278294 PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc = &PartialList->PartialDescriptors[iii];
279295280296 /* First check types */
···548564{
549565 ULONG i, ii;
550566 BOOLEAN Result = FALSE;
567567+ PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
551568569569+ FullDescriptor = &ResourceList->List[0];
552570 for (i = 0; i < ResourceList->Count; i++)
553571 {
554554- PCM_PARTIAL_RESOURCE_LIST ResList = &ResourceList->List[i].PartialResourceList;
572572+ PCM_PARTIAL_RESOURCE_LIST ResList = &FullDescriptor->PartialResourceList;
573573+ FullDescriptor = CmiGetNextResourceDescriptor(FullDescriptor);
574574+555575 for (ii = 0; ii < ResList->Count; ii++)
556576 {
577577+ /* Partial resource descriptors can be of variable size (CmResourceTypeDeviceSpecific),
578578+ but only one is allowed and it must be the last one in the list! */
557579 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc2 = &ResList->PartialDescriptors[ii];
558580559581 /* We don't care about shared resources */
···674696 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
675697 }
676698677677- return Result;
699699+ // Hacked, because after fixing resource list parsing
700700+ // we actually detect resource conflicts
701701+ return Silent ? Result : FALSE; // Result;
678702}
679703680704static
···937961{
938962 PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
939963 PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated;
964964+ PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
940965 ULONG i, j, ListSize;
941966 NTSTATUS Status;
942967···959984 }
960985 RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, ListSize);
961986987987+ FullDescriptor = &DeviceNode->ResourceList->List[0];
962988 for (i = 0; i < DeviceNode->ResourceList->Count; i++)
963989 {
964964- pPartialResourceList = &DeviceNode->ResourceList->List[i].PartialResourceList;
990990+ pPartialResourceList = &FullDescriptor->PartialResourceList;
991991+ FullDescriptor = CmiGetNextResourceDescriptor(FullDescriptor);
992992+965993 for (j = 0; j < pPartialResourceList->Count; j++)
966994 {
995995+ /* Partial resource descriptors can be of variable size (CmResourceTypeDeviceSpecific),
996996+ but only one is allowed and it must be the last one in the list! */
967997 DescriptorRaw = &pPartialResourceList->PartialDescriptors[j];
968968- DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j];
998998+999999+ /* Calculate the location of the translated resource descriptor */
10001000+ DescriptorTranslated = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)(
10011001+ (PUCHAR)DeviceNode->ResourceListTranslated +
10021002+ ((PUCHAR)DescriptorRaw - (PUCHAR)DeviceNode->ResourceList));
10031003+9691004 switch (DescriptorRaw->Type)
9701005 {
9711006 case CmResourceTypePort:
···9961031 }
9971032 case CmResourceTypeInterrupt:
9981033 {
10341034+ KIRQL Irql;
9991035 DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector(
10001036 DeviceNode->ResourceList->List[i].InterfaceType,
10011037 DeviceNode->ResourceList->List[i].BusNumber,
10021038 DescriptorRaw->u.Interrupt.Level,
10031039 DescriptorRaw->u.Interrupt.Vector,
10041004- (PKIRQL)&DescriptorTranslated->u.Interrupt.Level,
10401040+ &Irql,
10051041 &DescriptorTranslated->u.Interrupt.Affinity);
10061006-10421042+ DescriptorTranslated->u.Interrupt.Level = Irql;
10071043 if (!DescriptorTranslated->u.Interrupt.Vector)
10081044 {
10091045 Status = STATUS_UNSUCCESSFUL;
···11841220{
11851221 ULONG i, ii;
11861222 BOOLEAN Result = FALSE;
12231223+ PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
1187122412251225+ FullDescriptor = &ResourceList1->List[0];
11881226 for (i = 0; i < ResourceList1->Count; i++)
11891227 {
11901190- PCM_PARTIAL_RESOURCE_LIST ResList = &ResourceList1->List[i].PartialResourceList;
12281228+ PCM_PARTIAL_RESOURCE_LIST ResList = &FullDescriptor->PartialResourceList;
12291229+ FullDescriptor = CmiGetNextResourceDescriptor(FullDescriptor);
12301230+11911231 for (ii = 0; ii < ResList->Count; ii++)
11921232 {
12331233+ /* Partial resource descriptors can be of variable size (CmResourceTypeDeviceSpecific),
12341234+ but only one is allowed and it must be the last one in the list! */
11931235 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc = &ResList->PartialDescriptors[ii];
1194123611951237 Result = IopCheckResourceDescriptor(ResDesc,
+66
sdk/include/reactos/drivers/cmreslist.h
···11+/*
22+ * PROJECT: ReactOS Kernel
33+ * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
44+ * PURPOSE: Helper functions to parse CM_RESOURCE_LISTs
55+ * COPYRIGHT: Copyright 2020 Timo Kreuzer (timo.kreuzer@reactos.org)
66+ */
77+88+#include <wdm.h>
99+1010+//
1111+// Resource list helpers
1212+//
1313+1414+/* Usage note:
1515+ * As there can be only one variable-sized CM_PARTIAL_RESOURCE_DESCRIPTOR in the list (and it must be the last one),
1616+ * a right looping through resources can look like this:
1717+ *
1818+ * PCM_FULL_RESOURCE_DESCRIPTOR FullDesc = &ResourceList->List[0];
1919+ * for (ULONG i = 0; i < ResourceList->Count; i++, FullDesc = CmiGetNextResourceDescriptor(FullDesc))
2020+ * {
2121+ * for (ULONG j = 0; j < FullDesc->PartialResourceList.Count; j++)
2222+ * {
2323+ * PartialDesc = &FullDesc->PartialResourceList.PartialDescriptors[j];
2424+ * // work with PartialDesc
2525+ * }
2626+ * }
2727+ */
2828+2929+FORCEINLINE
3030+PCM_PARTIAL_RESOURCE_DESCRIPTOR
3131+CmiGetNextPartialDescriptor(
3232+ _In_ const CM_PARTIAL_RESOURCE_DESCRIPTOR *PartialDescriptor)
3333+{
3434+ const CM_PARTIAL_RESOURCE_DESCRIPTOR *NextDescriptor;
3535+3636+ /* Assume the descriptors are the fixed size ones */
3737+ NextDescriptor = PartialDescriptor + 1;
3838+3939+ /* But check if this is actually a variable-sized descriptor */
4040+ if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific)
4141+ {
4242+ /* Add the size of the variable section as well */
4343+ NextDescriptor = (PVOID)((ULONG_PTR)NextDescriptor +
4444+ PartialDescriptor->u.DeviceSpecificData.DataSize);
4545+ ASSERT(NextDescriptor >= PartialDescriptor + 1);
4646+ }
4747+4848+ /* Now the correct pointer has been computed, return it */
4949+ return (PCM_PARTIAL_RESOURCE_DESCRIPTOR)NextDescriptor;
5050+}
5151+5252+FORCEINLINE
5353+PCM_FULL_RESOURCE_DESCRIPTOR
5454+CmiGetNextResourceDescriptor(
5555+ _In_ const CM_FULL_RESOURCE_DESCRIPTOR *ResourceDescriptor)
5656+{
5757+ const CM_PARTIAL_RESOURCE_DESCRIPTOR *LastPartialDescriptor;
5858+5959+ /* Calculate the location of the last partial descriptor, which can have a
6060+ variable size! */
6161+ LastPartialDescriptor = &ResourceDescriptor->PartialResourceList.PartialDescriptors[
6262+ ResourceDescriptor->PartialResourceList.Count - 1];
6363+6464+ /* Next full resource descriptor follows the last partial descriptor */
6565+ return (PCM_FULL_RESOURCE_DESCRIPTOR)CmiGetNextPartialDescriptor(LastPartialDescriptor);
6666+}