2 * PROJECT: ReactOS Storport Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Storport helper functions
5 * COPYRIGHT: Copyright 2017 Eric Kohl (eric.kohl@reactos.org)
8 /* INCLUDES *******************************************************************/
16 /* FUNCTIONS ******************************************************************/
21 ForwardIrpAndWaitCompletion(
22 _In_ PDEVICE_OBJECT DeviceObject
,
26 if (Irp
->PendingReturned
)
27 KeSetEvent((PKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
28 return STATUS_MORE_PROCESSING_REQUIRED
;
34 _In_ PDEVICE_OBJECT LowerDevice
,
42 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
43 IoCopyCurrentIrpStackLocationToNext(Irp
);
45 IoSetCompletionRoutine(Irp
, ForwardIrpAndWaitCompletion
, &Event
, TRUE
, TRUE
, TRUE
);
47 Status
= IoCallDriver(LowerDevice
, Irp
);
48 if (Status
== STATUS_PENDING
)
50 Status
= KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
51 if (NT_SUCCESS(Status
))
52 Status
= Irp
->IoStatus
.Status
;
62 _In_ PDEVICE_OBJECT LowerDevice
,
67 IoSkipCurrentIrpStackLocation(Irp
);
68 return IoCallDriver(LowerDevice
, Irp
);
74 PDEVICE_OBJECT DeviceObject
)
80 Status
= IoGetDeviceProperty(DeviceObject
,
81 DevicePropertyBusTypeGuid
,
85 if (!NT_SUCCESS(Status
))
86 return InterfaceTypeUndefined
;
88 if (RtlCompareMemory(&Guid
, &GUID_BUS_TYPE_PCMCIA
, sizeof(GUID
)) == sizeof(GUID
))
90 else if (RtlCompareMemory(&Guid
, &GUID_BUS_TYPE_PCI
, sizeof(GUID
)) == sizeof(GUID
))
92 else if (RtlCompareMemory(&Guid
, &GUID_BUS_TYPE_ISAPNP
, sizeof(GUID
)) == sizeof(GUID
))
95 return InterfaceTypeUndefined
;
102 PCM_RESOURCE_LIST ResourceList
)
104 PCM_FULL_RESOURCE_DESCRIPTOR Descriptor
;
107 DPRINT1("GetResourceListSize(%p)\n", ResourceList
);
109 Size
= sizeof(CM_RESOURCE_LIST
);
110 if (ResourceList
->Count
== 0)
112 DPRINT1("Size: 0x%lx (%u)\n", Size
, Size
);
116 DPRINT1("ResourceList->Count: %lu\n", ResourceList
->Count
);
118 Descriptor
= &ResourceList
->List
[0];
120 DPRINT1("PartialResourceList->Count: %lu\n", Descriptor
->PartialResourceList
.Count
);
122 /* Add the size of the partial descriptors */
123 if (Descriptor
->PartialResourceList
.Count
> 1)
124 Size
+= (Descriptor
->PartialResourceList
.Count
- 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
126 DPRINT1("Size: 0x%lx (%u)\n", Size
, Size
);
134 PCM_RESOURCE_LIST Source
)
136 PCM_RESOURCE_LIST Destination
;
139 DPRINT1("CopyResourceList(%lu %p)\n",
142 /* Get the size of the resource list */
143 Size
= GetResourceListSize(Source
);
145 /* Allocate a new buffer */
146 Destination
= ExAllocatePoolWithTag(PoolType
,
149 if (Destination
== NULL
)
152 /* Copy the resource list */
153 RtlCopyMemory(Destination
,
163 PDEVICE_OBJECT DeviceObject
,
167 PBUS_INTERFACE_STANDARD Interface
,
168 PVOID InterfaceSpecificData
)
173 IO_STATUS_BLOCK IoStatus
;
174 PIO_STACK_LOCATION Stack
;
176 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
178 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_PNP
,
186 return STATUS_INSUFFICIENT_RESOURCES
;
188 Stack
= IoGetNextIrpStackLocation(Irp
);
190 Stack
->MajorFunction
= IRP_MJ_PNP
;
191 Stack
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
192 Stack
->Parameters
.QueryInterface
.InterfaceType
= Guid
;
193 Stack
->Parameters
.QueryInterface
.Size
= Size
;
194 Stack
->Parameters
.QueryInterface
.Version
= Version
;
195 Stack
->Parameters
.QueryInterface
.Interface
= (PINTERFACE
)Interface
;
196 Stack
->Parameters
.QueryInterface
.InterfaceSpecificData
= InterfaceSpecificData
;
198 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
200 Status
= IoCallDriver(DeviceObject
, Irp
);
201 if (Status
== STATUS_PENDING
)
203 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
205 Status
=IoStatus
.Status
;
213 TranslateResourceListAddress(
214 PFDO_DEVICE_EXTENSION DeviceExtension
,
215 INTERFACE_TYPE BusType
,
216 ULONG SystemIoBusNumber
,
217 STOR_PHYSICAL_ADDRESS IoAddress
,
220 PPHYSICAL_ADDRESS TranslatedAddress
)
222 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptorA
, FullDescriptorT
;
223 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorA
, PartialDescriptorT
;
226 DPRINT1("TranslateResourceListAddress(%p)\n", DeviceExtension
);
228 FullDescriptorA
= DeviceExtension
->AllocatedResources
->List
;
229 FullDescriptorT
= DeviceExtension
->TranslatedResources
->List
;
230 for (i
= 0; i
< DeviceExtension
->AllocatedResources
->Count
; i
++)
232 for (j
= 0; j
< FullDescriptorA
->PartialResourceList
.Count
; j
++)
234 PartialDescriptorA
= FullDescriptorA
->PartialResourceList
.PartialDescriptors
+ j
;
235 PartialDescriptorT
= FullDescriptorT
->PartialResourceList
.PartialDescriptors
+ j
;
237 switch (PartialDescriptorA
->Type
)
239 case CmResourceTypePort
:
240 DPRINT1("Port: 0x%I64x (0x%lx)\n",
241 PartialDescriptorA
->u
.Port
.Start
.QuadPart
,
242 PartialDescriptorA
->u
.Port
.Length
);
244 IoAddress
.QuadPart
>= PartialDescriptorA
->u
.Port
.Start
.QuadPart
&&
245 IoAddress
.QuadPart
+ NumberOfBytes
<= PartialDescriptorA
->u
.Port
.Start
.QuadPart
+ PartialDescriptorA
->u
.Port
.Length
)
247 TranslatedAddress
->QuadPart
= PartialDescriptorT
->u
.Port
.Start
.QuadPart
+
248 (IoAddress
.QuadPart
- PartialDescriptorA
->u
.Port
.Start
.QuadPart
);
253 case CmResourceTypeMemory
:
254 DPRINT1("Memory: 0x%I64x (0x%lx)\n",
255 PartialDescriptorA
->u
.Memory
.Start
.QuadPart
,
256 PartialDescriptorA
->u
.Memory
.Length
);
258 IoAddress
.QuadPart
>= PartialDescriptorA
->u
.Memory
.Start
.QuadPart
&&
259 IoAddress
.QuadPart
+ NumberOfBytes
<= PartialDescriptorA
->u
.Memory
.Start
.QuadPart
+ PartialDescriptorA
->u
.Memory
.Length
)
261 TranslatedAddress
->QuadPart
= PartialDescriptorT
->u
.Memory
.Start
.QuadPart
+
262 (IoAddress
.QuadPart
- PartialDescriptorA
->u
.Memory
.Start
.QuadPart
);
269 /* Advance to next CM_FULL_RESOURCE_DESCRIPTOR block in memory. */
270 FullDescriptorA
= (PCM_FULL_RESOURCE_DESCRIPTOR
)(FullDescriptorA
->PartialResourceList
.PartialDescriptors
+
271 FullDescriptorA
->PartialResourceList
.Count
);
273 FullDescriptorT
= (PCM_FULL_RESOURCE_DESCRIPTOR
)(FullDescriptorT
->PartialResourceList
.PartialDescriptors
+
274 FullDescriptorT
->PartialResourceList
.Count
);
282 GetResourceListInterrupt(
283 PFDO_DEVICE_EXTENSION DeviceExtension
,
286 KINTERRUPT_MODE
*InterruptMode
,
287 PBOOLEAN ShareVector
,
290 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor
;
291 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
294 DPRINT1("GetResourceListInterrupt(%p)\n",
297 FullDescriptor
= DeviceExtension
->TranslatedResources
->List
;
298 for (i
= 0; i
< DeviceExtension
->TranslatedResources
->Count
; i
++)
300 for (j
= 0; j
< FullDescriptor
->PartialResourceList
.Count
; j
++)
302 PartialDescriptor
= FullDescriptor
->PartialResourceList
.PartialDescriptors
+ j
;
304 switch (PartialDescriptor
->Type
)
306 case CmResourceTypeInterrupt
:
307 DPRINT1("Interrupt: Level %lu Vector %lu\n",
308 PartialDescriptor
->u
.Interrupt
.Level
,
309 PartialDescriptor
->u
.Interrupt
.Vector
);
311 *Vector
= PartialDescriptor
->u
.Interrupt
.Vector
;
312 *Irql
= (KIRQL
)PartialDescriptor
->u
.Interrupt
.Level
;
313 *InterruptMode
= (PartialDescriptor
->Flags
& CM_RESOURCE_INTERRUPT_LATCHED
) ? Latched
: LevelSensitive
;
314 *ShareVector
= (PartialDescriptor
->ShareDisposition
== CmResourceShareShared
) ? TRUE
: FALSE
;
315 *Affinity
= PartialDescriptor
->u
.Interrupt
.Affinity
;
317 return STATUS_SUCCESS
;
321 /* Advance to next CM_FULL_RESOURCE_DESCRIPTOR block in memory. */
322 FullDescriptor
= (PCM_FULL_RESOURCE_DESCRIPTOR
)(FullDescriptor
->PartialResourceList
.PartialDescriptors
+
323 FullDescriptor
->PartialResourceList
.Count
);
326 return STATUS_NOT_FOUND
;
331 AllocateAddressMapping(
332 PMAPPED_ADDRESS
*MappedAddressList
,
333 STOR_PHYSICAL_ADDRESS IoAddress
,
338 PMAPPED_ADDRESS Mapping
;
340 DPRINT1("AllocateAddressMapping()\n");
342 Mapping
= ExAllocatePoolWithTag(NonPagedPool
,
343 sizeof(MAPPED_ADDRESS
),
344 TAG_ADDRESS_MAPPING
);
347 DPRINT1("No memory!\n");
348 return STATUS_NO_MEMORY
;
351 RtlZeroMemory(Mapping
, sizeof(MAPPED_ADDRESS
));
353 Mapping
->NextMappedAddress
= *MappedAddressList
;
354 *MappedAddressList
= Mapping
;
356 Mapping
->IoAddress
= IoAddress
;
357 Mapping
->MappedAddress
= MappedAddress
;
358 Mapping
->NumberOfBytes
= NumberOfBytes
;
359 Mapping
->BusNumber
= BusNumber
;
361 return STATUS_SUCCESS
;