mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 05:26:58 +00:00
[STORPORT] Attach copies of the resource lists to the FDO device extension and use them to fill the access ranges in the port configuration.
Storahci does not crash on initialization any more. :-) CORE-13866
This commit is contained in:
parent
6808e7d25b
commit
3f5aeb9363
|
@ -74,6 +74,7 @@ PortFdoStartDevice(
|
|||
_In_ PFDO_DEVICE_EXTENSION DeviceExtension,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT1("PortFdoStartDevice(%p %p)\n",
|
||||
|
@ -81,6 +82,9 @@ PortFdoStartDevice(
|
|||
|
||||
ASSERT(DeviceExtension->ExtensionType == FdoExtension);
|
||||
|
||||
/* Get the current stack location */
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* Start the lower device if the FDO is in 'stopped' state */
|
||||
if (DeviceExtension->PnpState == dsStopped)
|
||||
{
|
||||
|
@ -95,6 +99,21 @@ PortFdoStartDevice(
|
|||
/* Change to the 'started' state */
|
||||
DeviceExtension->PnpState = dsStarted;
|
||||
|
||||
/* Copy the raw and translated resource lists into the device extension */
|
||||
if (Stack->Parameters.StartDevice.AllocatedResources != NULL &&
|
||||
Stack->Parameters.StartDevice.AllocatedResourcesTranslated != NULL)
|
||||
{
|
||||
DeviceExtension->AllocatedResources = CopyResourceList(NonPagedPool,
|
||||
Stack->Parameters.StartDevice.AllocatedResources);
|
||||
if (DeviceExtension->AllocatedResources == NULL)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
DeviceExtension->TranslatedResources = CopyResourceList(NonPagedPool,
|
||||
Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
|
||||
if (DeviceExtension->TranslatedResources == NULL)
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Start the miniport (FindAdapter & Initialize) */
|
||||
Status = PortFdoStartMiniport(DeviceExtension);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
|
|
@ -89,6 +89,147 @@ InitializeConfiguration(
|
|||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
AssignResourcesToConfiguration(
|
||||
_In_ PPORT_CONFIGURATION_INFORMATION PortConfiguration,
|
||||
_In_ PCM_RESOURCE_LIST ResourceList,
|
||||
_In_ ULONG NumberOfAccessRanges)
|
||||
{
|
||||
PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
|
||||
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
||||
PACCESS_RANGE AccessRange;
|
||||
INT i, j;
|
||||
ULONG RangeNumber = 0, Interrupt = 0, Dma = 0;
|
||||
|
||||
DPRINT1("AssignResourceToConfiguration(%p %p %lu)\n",
|
||||
PortConfiguration, ResourceList, NumberOfAccessRanges);
|
||||
|
||||
FullDescriptor = &ResourceList->List[0];
|
||||
for (i = 0; i < ResourceList->Count; i++)
|
||||
{
|
||||
PartialResourceList = &FullDescriptor->PartialResourceList;
|
||||
|
||||
for (j = 0; j < PartialResourceList->Count; j++)
|
||||
{
|
||||
PartialDescriptor = &PartialResourceList->PartialDescriptors[j];
|
||||
|
||||
switch (PartialDescriptor->Type)
|
||||
{
|
||||
case CmResourceTypePort:
|
||||
DPRINT1("Port: 0x%I64x (0x%lx)\n",
|
||||
PartialDescriptor->u.Port.Start.QuadPart,
|
||||
PartialDescriptor->u.Port.Length);
|
||||
if (RangeNumber < NumberOfAccessRanges)
|
||||
{
|
||||
AccessRange = &((*(PortConfiguration->AccessRanges))[RangeNumber]);
|
||||
AccessRange->RangeStart = PartialDescriptor->u.Port.Start;
|
||||
AccessRange->RangeLength = PartialDescriptor->u.Port.Length;
|
||||
AccessRange->RangeInMemory = FALSE;
|
||||
RangeNumber++;
|
||||
}
|
||||
break;
|
||||
|
||||
case CmResourceTypeMemory:
|
||||
DPRINT1("Memory: 0x%I64x (0x%lx)\n",
|
||||
PartialDescriptor->u.Memory.Start.QuadPart,
|
||||
PartialDescriptor->u.Memory.Length);
|
||||
if (RangeNumber < NumberOfAccessRanges)
|
||||
{
|
||||
AccessRange = &((*(PortConfiguration->AccessRanges))[RangeNumber]);
|
||||
AccessRange->RangeStart = PartialDescriptor->u.Memory.Start;
|
||||
AccessRange->RangeLength = PartialDescriptor->u.Memory.Length;
|
||||
AccessRange->RangeInMemory = TRUE;
|
||||
RangeNumber++;
|
||||
}
|
||||
break;
|
||||
|
||||
case CmResourceTypeInterrupt:
|
||||
DPRINT1("Interrupt: Level %lu Vector %lu\n",
|
||||
PartialDescriptor->u.Interrupt.Level,
|
||||
PartialDescriptor->u.Interrupt.Vector);
|
||||
if (Interrupt == 0)
|
||||
{
|
||||
/* Copy interrupt data */
|
||||
PortConfiguration->BusInterruptLevel = PartialDescriptor->u.Interrupt.Level;
|
||||
PortConfiguration->BusInterruptVector = PartialDescriptor->u.Interrupt.Vector;
|
||||
|
||||
/* Set interrupt mode accordingly to the resource */
|
||||
if (PartialDescriptor->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
|
||||
{
|
||||
PortConfiguration->InterruptMode = Latched;
|
||||
}
|
||||
else if (PartialDescriptor->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)
|
||||
{
|
||||
PortConfiguration->InterruptMode = LevelSensitive;
|
||||
}
|
||||
}
|
||||
else if (Interrupt == 1)
|
||||
{
|
||||
/* Copy interrupt data */
|
||||
PortConfiguration->BusInterruptLevel2 = PartialDescriptor->u.Interrupt.Level;
|
||||
PortConfiguration->BusInterruptVector2 = PartialDescriptor->u.Interrupt.Vector;
|
||||
|
||||
/* Set interrupt mode accordingly to the resource */
|
||||
if (PartialDescriptor->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
|
||||
{
|
||||
PortConfiguration->InterruptMode2 = Latched;
|
||||
}
|
||||
else if (PartialDescriptor->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)
|
||||
{
|
||||
PortConfiguration->InterruptMode2 = LevelSensitive;
|
||||
}
|
||||
}
|
||||
Interrupt++;
|
||||
break;
|
||||
|
||||
case CmResourceTypeDma:
|
||||
DPRINT1("Dma: Channel: %lu Port: %lu\n",
|
||||
PartialDescriptor->u.Dma.Channel,
|
||||
PartialDescriptor->u.Dma.Port);
|
||||
if (Dma == 0)
|
||||
{
|
||||
PortConfiguration->DmaChannel = PartialDescriptor->u.Dma.Channel;
|
||||
PortConfiguration->DmaPort = PartialDescriptor->u.Dma.Port;
|
||||
|
||||
if (PartialDescriptor->Flags & CM_RESOURCE_DMA_8)
|
||||
PortConfiguration->DmaWidth = Width8Bits;
|
||||
else if ((PartialDescriptor->Flags & CM_RESOURCE_DMA_16) ||
|
||||
(PartialDescriptor->Flags & CM_RESOURCE_DMA_8_AND_16))
|
||||
PortConfiguration->DmaWidth = Width16Bits;
|
||||
else if (PartialDescriptor->Flags & CM_RESOURCE_DMA_32)
|
||||
PortConfiguration->DmaWidth = Width32Bits;
|
||||
}
|
||||
else if (Dma == 1)
|
||||
{
|
||||
PortConfiguration->DmaChannel2 = PartialDescriptor->u.Dma.Channel;
|
||||
PortConfiguration->DmaPort2 = PartialDescriptor->u.Dma.Port;
|
||||
|
||||
if (PartialDescriptor->Flags & CM_RESOURCE_DMA_8)
|
||||
PortConfiguration->DmaWidth2 = Width8Bits;
|
||||
else if ((PartialDescriptor->Flags & CM_RESOURCE_DMA_16) ||
|
||||
(PartialDescriptor->Flags & CM_RESOURCE_DMA_8_AND_16))
|
||||
PortConfiguration->DmaWidth2 = Width16Bits;
|
||||
else if (PartialDescriptor->Flags & CM_RESOURCE_DMA_32)
|
||||
PortConfiguration->DmaWidth2 = Width32Bits;
|
||||
}
|
||||
Dma++;
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("Other: %u\n", PartialDescriptor->Type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Advance to next CM_FULL_RESOURCE_DESCRIPTOR block in memory. */
|
||||
FullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)(FullDescriptor->PartialResourceList.PartialDescriptors +
|
||||
FullDescriptor->PartialResourceList.Count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
MiniportInitialize(
|
||||
_In_ PMINIPORT Miniport,
|
||||
|
@ -126,8 +267,15 @@ MiniportInitialize(
|
|||
InitData,
|
||||
DeviceExtension->BusNumber,
|
||||
DeviceExtension->SlotNumber);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
/* Assign the resources to the port configuration */
|
||||
AssignResourcesToConfiguration(&Miniport->PortConfig,
|
||||
DeviceExtension->AllocatedResources,
|
||||
InitData->NumberOfAccessRanges);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -150,6 +298,7 @@ MiniportFindAdapter(
|
|||
&Reserved);
|
||||
DPRINT1("HwFindAdapter() returned %lu\n", Result);
|
||||
|
||||
/* Convert the result to a status code */
|
||||
switch (Result)
|
||||
{
|
||||
case SP_RETURN_NOT_FOUND:
|
||||
|
|
|
@ -95,4 +95,76 @@ GetBusInterface(
|
|||
return InterfaceTypeUndefined;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
ULONG
|
||||
GetResourceListSize(
|
||||
PCM_RESOURCE_LIST ResourceList)
|
||||
{
|
||||
PCM_FULL_RESOURCE_DESCRIPTOR Descriptor;
|
||||
INT i;
|
||||
ULONG Size;
|
||||
|
||||
DPRINT1("GetResourceListSize(%p)\n", ResourceList);
|
||||
|
||||
Size = sizeof(CM_RESOURCE_LIST);
|
||||
if (ResourceList->Count == 0)
|
||||
{
|
||||
DPRINT1("Size: 0x%lx (%u)\n", Size, Size);
|
||||
return Size;
|
||||
}
|
||||
|
||||
DPRINT1("ResourceList->Count: %lu\n", ResourceList->Count);
|
||||
|
||||
Descriptor = &ResourceList->List[0];
|
||||
for (i = 0; i < ResourceList->Count; i++)
|
||||
{
|
||||
/* Process resources in CM_FULL_RESOURCE_DESCRIPTOR block number ix. */
|
||||
|
||||
DPRINT1("PartialResourceList->Count: %lu\n", Descriptor->PartialResourceList.Count);
|
||||
|
||||
/* Add the size of the current full descriptor */
|
||||
Size += sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
|
||||
(Descriptor->PartialResourceList.Count - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
|
||||
|
||||
/* Advance to next CM_FULL_RESOURCE_DESCRIPTOR block in memory. */
|
||||
Descriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)(Descriptor->PartialResourceList.PartialDescriptors +
|
||||
Descriptor->PartialResourceList.Count);
|
||||
}
|
||||
|
||||
DPRINT1("Size: 0x%lx (%u)\n", Size, Size);
|
||||
return Size;
|
||||
}
|
||||
|
||||
|
||||
PCM_RESOURCE_LIST
|
||||
CopyResourceList(
|
||||
POOL_TYPE PoolType,
|
||||
PCM_RESOURCE_LIST Source)
|
||||
{
|
||||
PCM_RESOURCE_LIST Destination;
|
||||
ULONG Size;
|
||||
|
||||
DPRINT1("CopyResourceList(%lu %p)\n",
|
||||
PoolType, Source);
|
||||
|
||||
/* Get the size of the resource list */
|
||||
Size = GetResourceListSize(Source);
|
||||
|
||||
/* Allocate a new buffer */
|
||||
Destination = ExAllocatePoolWithTag(PoolType,
|
||||
Size,
|
||||
TAG_RESOURCE_LIST);
|
||||
if (Destination == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Copy the resource list */
|
||||
RtlCopyMemory(Destination,
|
||||
Source,
|
||||
Size);
|
||||
|
||||
return Destination;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define TAG_INIT_DATA 'DItS'
|
||||
#define TAG_MINIPORT_DATA 'DMtS'
|
||||
#define TAG_ACCRESS_RANGE 'RAtS'
|
||||
#define TAG_RESOURCE_LIST 'LRtS'
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -90,6 +91,8 @@ typedef struct _FDO_DEVICE_EXTENSION
|
|||
MINIPORT Miniport;
|
||||
ULONG BusNumber;
|
||||
ULONG SlotNumber;
|
||||
PCM_RESOURCE_LIST AllocatedResources;
|
||||
PCM_RESOURCE_LIST TranslatedResources;
|
||||
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||
|
||||
|
||||
|
@ -147,6 +150,12 @@ INTERFACE_TYPE
|
|||
GetBusInterface(
|
||||
PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
PCM_RESOURCE_LIST
|
||||
CopyResourceList(
|
||||
POOL_TYPE PoolType,
|
||||
PCM_RESOURCE_LIST Source);
|
||||
|
||||
|
||||
/* pdo.c */
|
||||
|
||||
NTSTATUS
|
||||
|
|
Loading…
Reference in a new issue