[STORPORT] Get the interrupt from the resource list, connect it and call the miniports HwInterrupt routine.

CORE-13866
This commit is contained in:
Eric Kohl 2017-10-23 23:21:58 +02:00
parent deb9c5416f
commit 5cfc1e3152
4 changed files with 167 additions and 0 deletions

View file

@ -15,6 +15,90 @@
/* FUNCTIONS ******************************************************************/
static
BOOLEAN
NTAPI
PortFdoInterruptRoutine(
_In_ PKINTERRUPT Interrupt,
_In_ PVOID ServiceContext)
{
PFDO_DEVICE_EXTENSION DeviceExtension;
DPRINT1("PortFdoInterruptRoutine(%p %p)\n",
Interrupt, ServiceContext);
DeviceExtension = (PFDO_DEVICE_EXTENSION)ServiceContext;
return MiniportHwInterrupt(&DeviceExtension->Miniport);
}
static
NTSTATUS
PortFdoConnectInterrupt(
_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
{
ULONG Vector;
KIRQL Irql;
KINTERRUPT_MODE InterruptMode;
BOOLEAN ShareVector;
KAFFINITY Affinity;
NTSTATUS Status;
DPRINT1("PortFdoConnectInterrupt(%p)\n",
DeviceExtension);
/* No resources, no interrupt. Done! */
if (DeviceExtension->AllocatedResources == NULL ||
DeviceExtension->TranslatedResources == NULL)
{
DPRINT1("Checkpoint\n");
return STATUS_SUCCESS;
}
/* Get the interrupt data from the resource list */
Status = GetResourceListInterrupt(DeviceExtension,
&Vector,
&Irql,
&InterruptMode,
&ShareVector,
&Affinity);
if (!NT_SUCCESS(Status))
{
DPRINT1("GetResourceListInterrupt() failed (Status 0x%08lx)\n", Status);
return Status;
}
DPRINT1("Vector: %lu\n", Vector);
DPRINT1("Irql: %lu\n", Irql);
DPRINT1("Affinity: 0x%08lx\n", Affinity);
/* Connect the interrupt */
Status = IoConnectInterrupt(&DeviceExtension->Interrupt,
PortFdoInterruptRoutine,
DeviceExtension,
NULL,
Vector,
Irql,
Irql,
InterruptMode,
ShareVector,
Affinity,
FALSE);
if (NT_SUCCESS(Status))
{
DeviceExtension->InterruptIrql = Irql;
}
else
{
DPRINT1("IoConnectInterrupt() failed (Status 0x%08lx)\n", Status);
}
return Status;
}
static
NTSTATUS
PortFdoStartMiniport(
@ -55,6 +139,10 @@ PortFdoStartMiniport(
return Status;
}
Status = PortFdoConnectInterrupt(DeviceExtension);
/* Call the miniports HwInitialize function */
Status = MiniportHwInitialize(&DeviceExtension->Miniport);
if (!NT_SUCCESS(Status))

View file

@ -346,4 +346,20 @@ MiniportHwInitialize(
return Result ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
BOOLEAN
MiniportHwInterrupt(
_In_ PMINIPORT Miniport)
{
BOOLEAN Result;
DPRINT1("MiniportHwInterrupt(%p)\n",
Miniport);
Result = Miniport->InitData->HwInterrupt(&Miniport->MiniportExtension->HwDeviceExtension);
DPRINT1("HwInterrupt() returned %u\n", Result);
return Result;
}
/* EOF */

View file

@ -287,6 +287,55 @@ TranslateResourceListAddress(
}
NTSTATUS
GetResourceListInterrupt(
PFDO_DEVICE_EXTENSION DeviceExtension,
PULONG Vector,
PKIRQL Irql,
KINTERRUPT_MODE *InterruptMode,
PBOOLEAN ShareVector,
PKAFFINITY Affinity)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
INT i, j;
DPRINT1("GetResourceListInterrupt(%p)\n",
DeviceExtension);
FullDescriptor = DeviceExtension->TranslatedResources->List;
for (i = 0; i < DeviceExtension->TranslatedResources->Count; i++)
{
for (j = 0; j < FullDescriptor->PartialResourceList.Count; j++)
{
PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors + j;
switch (PartialDescriptor->Type)
{
case CmResourceTypeInterrupt:
DPRINT1("Interrupt: Level %lu Vector %lu\n",
PartialDescriptor->u.Interrupt.Level,
PartialDescriptor->u.Interrupt.Vector);
*Vector = PartialDescriptor->u.Interrupt.Vector;
*Irql = (KIRQL)PartialDescriptor->u.Interrupt.Level;
*InterruptMode = (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;
*ShareVector = (PartialDescriptor->ShareDisposition == CmResourceShareShared) ? TRUE : FALSE;
*Affinity = PartialDescriptor->u.Interrupt.Affinity;
return STATUS_SUCCESS;
}
}
/* Advance to next CM_FULL_RESOURCE_DESCRIPTOR block in memory. */
FullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)(FullDescriptor->PartialResourceList.PartialDescriptors +
FullDescriptor->PartialResourceList.Count);
}
return STATUS_NOT_FOUND;
}
NTSTATUS
AllocateAddressMapping(
PMAPPED_ADDRESS *MappedAddressList,

View file

@ -101,6 +101,8 @@ typedef struct _FDO_DEVICE_EXTENSION
PHYSICAL_ADDRESS UncachedExtensionPhysicalBase;
ULONG UncachedExtensionSize;
PHW_PASSIVE_INITIALIZE_ROUTINE HwPassiveInitRoutine;
PKINTERRUPT Interrupt;
ULONG InterruptIrql;
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
@ -140,6 +142,9 @@ NTSTATUS
MiniportHwInitialize(
_In_ PMINIPORT Miniport);
BOOLEAN
MiniportHwInterrupt(
_In_ PMINIPORT Miniport);
/* misc.c */
@ -182,6 +187,15 @@ TranslateResourceListAddress(
BOOLEAN InIoSpace,
PPHYSICAL_ADDRESS TranslatedAddress);
NTSTATUS
GetResourceListInterrupt(
PFDO_DEVICE_EXTENSION DeviceExtension,
PULONG Vector,
PKIRQL Irql,
KINTERRUPT_MODE *InterruptMode,
PBOOLEAN ShareVector,
PKAFFINITY Affinity);
NTSTATUS
AllocateAddressMapping(
PMAPPED_ADDRESS *MappedAddressList,