@@ -275,6 +275,69 @@ IopFindInterruptResource(
275275 return FALSE;
276276}
277277
278+ static
279+ VOID
280+ IopDropStaleLineInterrupts (
281+ IN PCM_RESOURCE_LIST ResourceList )
282+ {
283+ PCM_PARTIAL_RESOURCE_LIST PartialList ;
284+ PCM_PARTIAL_RESOURCE_DESCRIPTOR Desc ;
285+ ULONG i ;
286+ BOOLEAN HasMessageInterrupt = FALSE;
287+
288+ if (!ResourceList || ResourceList -> Count == 0 )
289+ return ;
290+
291+ PartialList = & ResourceList -> List [0 ].PartialResourceList ;
292+
293+ /*
294+ * Compaction below assumes fixed-size partial descriptors. A variable-length
295+ * CmResourceTypeDeviceSpecific descriptor would break the shift, so bail out
296+ * if one is present (it never is for a PCI interrupt assignment).
297+ */
298+ for (i = 0 ; i < PartialList -> Count ; i ++ )
299+ {
300+ Desc = & PartialList -> PartialDescriptors [i ];
301+ if (Desc -> Type == CmResourceTypeDeviceSpecific )
302+ return ;
303+ if (Desc -> Type == CmResourceTypeInterrupt &&
304+ (Desc -> Flags & CM_RESOURCE_INTERRUPT_MESSAGE ))
305+ {
306+ HasMessageInterrupt = TRUE;
307+ }
308+ }
309+
310+ if (!HasMessageInterrupt )
311+ return ;
312+
313+ /*
314+ * The device was assigned an MSI/MSI-X interrupt. Any legacy line-based
315+ * interrupt that survived from the boot configuration is stale: it was only
316+ * the IO_RESOURCE_ALTERNATIVE fallback for the preferred MSI requirement,
317+ * which we skipped once the MSI was satisfied. MSI and INTx are mutually
318+ * exclusive on a PCI function, so leaving it in would make the device claim
319+ * both a message-signalled vector and an INTx line. Drop the line interrupt.
320+ */
321+ for (i = 0 ; i < PartialList -> Count ; )
322+ {
323+ Desc = & PartialList -> PartialDescriptors [i ];
324+ if (Desc -> Type == CmResourceTypeInterrupt &&
325+ !(Desc -> Flags & CM_RESOURCE_INTERRUPT_MESSAGE ))
326+ {
327+ ULONG Remaining = PartialList -> Count - i - 1 ;
328+ if (Remaining )
329+ {
330+ RtlMoveMemory (Desc , Desc + 1 ,
331+ Remaining * sizeof (CM_PARTIAL_RESOURCE_DESCRIPTOR ));
332+ }
333+ PartialList -> Count -- ;
334+ DPRINT1 ("Dropped stale legacy INTx interrupt (MSI/MSI-X assigned)\n" );
335+ continue ;
336+ }
337+ i ++ ;
338+ }
339+ }
340+
278341NTSTATUS NTAPI
279342IopFixupResourceListWithRequirements (
280343 IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList ,
@@ -596,6 +659,9 @@ IopFixupResourceListWithRequirements(
596659 continue ;
597660 }
598661
662+ /* Drop any stale boot INTx left over once the preferred MSI was assigned */
663+ IopDropStaleLineInterrupts (* ResourceList );
664+
599665 /* We're done because we satisfied one of the alternate lists */
600666 return STATUS_SUCCESS ;
601667 }
0 commit comments