2 * PROJECT: ReactOS Storport Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Storport driver main file
5 * COPYRIGHT: Copyright 2017 Eric Kohl (eric.kohl@reactos.org)
8 /* INCLUDES *******************************************************************/
16 /* GLOBALS ********************************************************************/
21 /* FUNCTIONS ******************************************************************/
25 PortAddDriverInitData(
26 PDRIVER_OBJECT_EXTENSION DriverExtension
,
27 PHW_INITIALIZATION_DATA HwInitializationData
)
29 PDRIVER_INIT_DATA InitData
;
31 DPRINT1("PortAddDriverInitData()\n");
33 InitData
= ExAllocatePoolWithTag(NonPagedPool
,
34 sizeof(DRIVER_INIT_DATA
),
37 return STATUS_NO_MEMORY
;
39 RtlCopyMemory(&InitData
->HwInitData
,
41 sizeof(HW_INITIALIZATION_DATA
));
43 InsertHeadList(&DriverExtension
->InitDataListHead
,
46 return STATUS_SUCCESS
;
52 PortDeleteDriverInitData(
53 PDRIVER_OBJECT_EXTENSION DriverExtension
)
55 PDRIVER_INIT_DATA InitData
;
56 PLIST_ENTRY ListEntry
;
58 DPRINT1("PortDeleteDriverInitData()\n");
60 ListEntry
= DriverExtension
->InitDataListHead
.Flink
;
61 while (ListEntry
!= &DriverExtension
->InitDataListHead
)
63 InitData
= CONTAINING_RECORD(ListEntry
,
67 RemoveEntryList(&InitData
->Entry
);
69 ExFreePoolWithTag(InitData
,
72 ListEntry
= DriverExtension
->InitDataListHead
.Flink
;
77 PHW_INITIALIZATION_DATA
78 PortGetDriverInitData(
79 PDRIVER_OBJECT_EXTENSION DriverExtension
,
80 INTERFACE_TYPE InterfaceType
)
82 PDRIVER_INIT_DATA InitData
;
83 PLIST_ENTRY ListEntry
;
85 DPRINT1("PortGetDriverInitData()\n");
87 ListEntry
= DriverExtension
->InitDataListHead
.Flink
;
88 while (ListEntry
!= &DriverExtension
->InitDataListHead
)
90 InitData
= CONTAINING_RECORD(ListEntry
,
93 if (InitData
->HwInitData
.AdapterInterfaceType
== InterfaceType
)
94 return &InitData
->HwInitData
;
96 ListEntry
= ListEntry
->Flink
;
107 _In_ PDRIVER_OBJECT DriverObject
,
108 _In_ PDEVICE_OBJECT PhysicalDeviceObject
)
110 PDRIVER_OBJECT_EXTENSION DriverObjectExtension
;
111 PFDO_DEVICE_EXTENSION DeviceExtension
= NULL
;
112 WCHAR NameBuffer
[80];
113 UNICODE_STRING DeviceName
;
114 PDEVICE_OBJECT Fdo
= NULL
;
115 KLOCK_QUEUE_HANDLE LockHandle
;
118 DPRINT1("PortAddDevice(%p %p)\n",
119 DriverObject
, PhysicalDeviceObject
);
121 ASSERT(DriverObject
);
122 ASSERT(PhysicalDeviceObject
);
125 L
"\\Device\\RaidPort%lu",
127 RtlInitUnicodeString(&DeviceName
, NameBuffer
);
130 DPRINT1("Creating device: %wZ\n", &DeviceName
);
132 /* Create the port device */
133 Status
= IoCreateDevice(DriverObject
,
134 sizeof(FDO_DEVICE_EXTENSION
),
136 FILE_DEVICE_CONTROLLER
,
137 FILE_DEVICE_SECURE_OPEN
,
140 if (!NT_SUCCESS(Status
))
142 DPRINT1("IoCreateDevice() failed (Status 0x%08lx)\n", Status
);
146 DPRINT1("Created device: %wZ (%p)\n", &DeviceName
, Fdo
);
148 /* Initialize the device */
149 Fdo
->Flags
|= DO_DIRECT_IO
;
150 Fdo
->Flags
|= DO_POWER_PAGABLE
;
152 /* Initialize the device extension */
153 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
154 RtlZeroMemory(DeviceExtension
, sizeof(FDO_DEVICE_EXTENSION
));
156 DeviceExtension
->ExtensionType
= FdoExtension
;
158 DeviceExtension
->Device
= Fdo
;
159 DeviceExtension
->PhysicalDevice
= PhysicalDeviceObject
;
161 DeviceExtension
->PnpState
= dsStopped
;
163 /* Attach the FDO to the device stack */
164 Status
= IoAttachDeviceToDeviceStackSafe(Fdo
,
165 PhysicalDeviceObject
,
166 &DeviceExtension
->LowerDevice
);
167 if (!NT_SUCCESS(Status
))
169 DPRINT1("IoAttachDeviceToDeviceStackSafe() failed (Status 0x%08lx)\n", Status
);
174 /* Insert the FDO to the drivers FDO list */
175 DriverObjectExtension
= IoGetDriverObjectExtension(DriverObject
,
177 ASSERT(DriverObjectExtension
->ExtensionType
== DriverExtension
);
179 DeviceExtension
->DriverExtension
= DriverObjectExtension
;
181 KeAcquireInStackQueuedSpinLock(&DriverObjectExtension
->AdapterListLock
,
184 InsertHeadList(&DriverObjectExtension
->AdapterListHead
,
185 &DeviceExtension
->AdapterListEntry
);
186 DriverObjectExtension
->AdapterCount
++;
188 KeReleaseInStackQueuedSpinLock(&LockHandle
);
190 /* The device has been initialized */
191 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
193 DPRINT1("PortAddDevice() done (Status 0x%08lx)\n", Status
);
203 _In_ PDRIVER_OBJECT DriverObject
)
205 PDRIVER_OBJECT_EXTENSION DriverExtension
;
207 DPRINT1("PortUnload(%p)\n",
210 DriverExtension
= IoGetDriverObjectExtension(DriverObject
,
212 if (DriverExtension
!= NULL
)
214 PortDeleteDriverInitData(DriverExtension
);
223 IN PDEVICE_OBJECT DeviceObject
,
226 DPRINT1("PortDispatchCreate(%p %p)\n",
229 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
230 Irp
->IoStatus
.Information
= FILE_OPENED
;
232 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
234 return STATUS_SUCCESS
;
242 IN PDEVICE_OBJECT DeviceObject
,
245 DPRINT1("PortDispatchClose(%p %p)\n",
248 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
249 Irp
->IoStatus
.Information
= 0;
251 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
253 return STATUS_SUCCESS
;
260 PortDispatchDeviceControl(
261 IN PDEVICE_OBJECT DeviceObject
,
264 DPRINT1("PortDispatchDeviceControl(%p %p)\n",
267 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
268 Irp
->IoStatus
.Information
= 0;
270 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
272 return STATUS_SUCCESS
;
280 IN PDEVICE_OBJECT DeviceObject
,
283 DPRINT1("PortDispatchScsi(%p %p)\n",
286 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
287 Irp
->IoStatus
.Information
= 0;
289 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
291 return STATUS_SUCCESS
;
298 PortDispatchSystemControl(
299 IN PDEVICE_OBJECT DeviceObject
,
302 DPRINT1("PortDispatchSystemControl(%p %p)\n",
305 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
306 Irp
->IoStatus
.Information
= 0;
308 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
310 return STATUS_SUCCESS
;
318 IN PDEVICE_OBJECT DeviceObject
,
321 PFDO_DEVICE_EXTENSION DeviceExtension
;
323 DPRINT1("PortDispatchPnp(%p %p)\n",
326 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
327 DPRINT1("ExtensionType: %u\n", DeviceExtension
->ExtensionType
);
329 switch (DeviceExtension
->ExtensionType
)
332 return PortFdoPnp(DeviceObject
,
336 return PortPdoPnp(DeviceObject
,
340 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
341 Irp
->IoStatus
.Information
= 0;
342 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
343 return STATUS_UNSUCCESSFUL
;
352 IN PDEVICE_OBJECT DeviceObject
,
355 DPRINT1("PortDispatchPower(%p %p)\n",
358 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
359 Irp
->IoStatus
.Information
= 0;
361 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
363 return STATUS_SUCCESS
;
367 /* PUBLIC FUNCTIONS ***********************************************************/
375 _In_ PDRIVER_OBJECT DriverObject
,
376 _In_ PUNICODE_STRING RegistryPath
)
378 DPRINT1("DriverEntry(%p %p)\n", DriverObject
, RegistryPath
);
379 return STATUS_SUCCESS
;
389 StorPortAllocateRegistryBuffer(
390 _In_ PVOID HwDeviceExtension
,
393 DPRINT1("StorPortAllocateRegistryBuffer()\n");
406 _In_ PVOID HwDeviceExtension
,
407 _In_ ULONG RequestsToComplete
)
409 DPRINT1("StorPortBuzy()\n");
421 StorPortCompleteRequest(
422 _In_ PVOID HwDeviceExtension
,
426 _In_ UCHAR SrbStatus
)
428 DPRINT1("StorPortCompleteRequest()\n");
439 StorPortConvertPhysicalAddressToUlong(
440 _In_ STOR_PHYSICAL_ADDRESS Address
)
442 DPRINT1("StorPortConvertPhysicalAddressToUlong()\n");
444 return Address
.u
.LowPart
;
452 STOR_PHYSICAL_ADDRESS
454 StorPortConvertUlongToPhysicalAddress(
455 _In_ ULONG_PTR UlongAddress
)
457 STOR_PHYSICAL_ADDRESS Address
;
459 DPRINT1("StorPortConvertUlongToPhysicalAddress()\n");
461 Address
.QuadPart
= UlongAddress
;
472 _In_ ULONG DebugPrintLevel
,
473 _In_ PCHAR DebugMessage
,
478 va_start(ap
, DebugMessage
);
479 vDbgPrintExWithPrefix("STORMINI: ", 0x58, DebugPrintLevel
, DebugMessage
, ap
);
491 _In_ PVOID HwDeviceExtension
,
495 _In_ ULONG RequestsToComplete
)
497 DPRINT1("StorPortDeviceBusy()\n");
510 _In_ PVOID HwDeviceExtension
,
515 DPRINT1("StorPortDeviceReady()\n");
527 StorPortFreeDeviceBase(
528 _In_ PVOID HwDeviceExtension
,
529 _In_ PVOID MappedAddress
)
531 DPRINT1("StorPortFreeDeviceBase()\n");
541 StorPortFreeRegistryBuffer(
542 _In_ PVOID HwDeviceExtension
,
545 DPRINT1("StorPortFreeRegistryBuffer()\n");
557 _In_ PVOID DeviceExtension
,
558 _In_ ULONG BusDataType
,
559 _In_ ULONG SystemIoBusNumber
,
560 _In_ ULONG SlotNumber
,
561 _Out_
_When_(Length
!= 0, _Out_writes_bytes_(Length
)) PVOID Buffer
,
564 PMINIPORT_DEVICE_EXTENSION MiniportExtension
;
565 PBUS_INTERFACE_STANDARD Interface
;
568 DPRINT1("StorPortGetBusData(%p %lu %lu %lu %p %lu)\n",
569 DeviceExtension
, BusDataType
, SystemIoBusNumber
, SlotNumber
, Buffer
, Length
);
571 MiniportExtension
= CONTAINING_RECORD(DeviceExtension
,
572 MINIPORT_DEVICE_EXTENSION
,
574 DPRINT1("DeviceExtension %p MiniportExtension %p\n",
575 DeviceExtension
, MiniportExtension
);
577 Interface
= &MiniportExtension
->Miniport
->DeviceExtension
->BusInterface
;
579 if (BusDataType
== 4)
582 ReturnLength
= Interface
->GetBusData(Interface
->Context
,
587 DPRINT1("ReturnLength: %lu\n", ReturnLength
);
599 StorPortGetDeviceBase(
600 _In_ PVOID HwDeviceExtension
,
601 _In_ INTERFACE_TYPE BusType
,
602 _In_ ULONG SystemIoBusNumber
,
603 _In_ STOR_PHYSICAL_ADDRESS IoAddress
,
604 _In_ ULONG NumberOfBytes
,
605 _In_ BOOLEAN InIoSpace
)
607 DPRINT1("StorPortGetDeviceBase()\n");
619 StorPortGetLogicalUnit(
620 _In_ PVOID HwDeviceExtension
,
625 DPRINT1("StorPortGetLogicalUnit()\n");
635 STOR_PHYSICAL_ADDRESS
637 StorPortGetPhysicalAddress(
638 _In_ PVOID HwDeviceExtension
,
639 _In_opt_ PSCSI_REQUEST_BLOCK Srb
,
640 _In_ PVOID VirtualAddress
,
643 STOR_PHYSICAL_ADDRESS PhysicalAddress
;
645 DPRINT1("StorPortGetPhysicalAddress(%p %p %p %p)\n",
646 HwDeviceExtension
, Srb
, VirtualAddress
, Length
);
650 PhysicalAddress
.QuadPart
= (LONGLONG
)0;
652 return PhysicalAddress
;
660 PSTOR_SCATTER_GATHER_LIST
662 StorPortGetScatterGatherList(
663 _In_ PVOID DeviceExtension
,
664 _In_ PSCSI_REQUEST_BLOCK Srb
)
666 DPRINT1("StorPortGetScatterGatherList()\n");
679 _In_ PVOID DeviceExtension
,
685 DPRINT("StorPortGetSrb()\n");
696 StorPortGetUncachedExtension(
697 _In_ PVOID HwDeviceExtension
,
698 _In_ PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
699 _In_ ULONG NumberOfBytes
)
701 DPRINT1("StorPortGetUncachedExtension(%p %p %lu)\n",
702 HwDeviceExtension
, ConfigInfo
, NumberOfBytes
);
714 StorPortGetVirtualAddress(
715 _In_ PVOID HwDeviceExtension
,
716 _In_ STOR_PHYSICAL_ADDRESS PhysicalAddress
)
718 DPRINT1("StorPortGetVirtualAddress(%p %I64x)\n",
719 HwDeviceExtension
, PhysicalAddress
.QuadPart
);
732 _In_ PVOID Argument1
,
733 _In_ PVOID Argument2
,
734 _In_
struct _HW_INITIALIZATION_DATA
*HwInitializationData
,
735 _In_opt_ PVOID HwContext
)
737 PDRIVER_OBJECT DriverObject
= (PDRIVER_OBJECT
)Argument1
;
738 PUNICODE_STRING RegistryPath
= (PUNICODE_STRING
)Argument2
;
739 PDRIVER_OBJECT_EXTENSION DriverObjectExtension
;
740 NTSTATUS Status
= STATUS_SUCCESS
;
742 DPRINT1("StorPortInitialize(%p %p %p %p)\n",
743 Argument1
, Argument2
, HwInitializationData
, HwContext
);
745 DPRINT1("HwInitializationDataSize: %lu\n", HwInitializationData
->HwInitializationDataSize
);
746 DPRINT1("AdapterInterfaceType: %u\n", HwInitializationData
->AdapterInterfaceType
);
747 DPRINT1("HwInitialize: %p\n", HwInitializationData
->HwInitialize
);
748 DPRINT1("HwStartIo: %p\n", HwInitializationData
->HwStartIo
);
749 DPRINT1("HwInterrupt: %p\n", HwInitializationData
->HwInterrupt
);
750 DPRINT1("HwFindAdapter: %p\n", HwInitializationData
->HwFindAdapter
);
751 DPRINT1("HwResetBus: %p\n", HwInitializationData
->HwResetBus
);
752 DPRINT1("HwDmaStarted: %p\n", HwInitializationData
->HwDmaStarted
);
753 DPRINT1("HwAdapterState: %p\n", HwInitializationData
->HwAdapterState
);
754 DPRINT1("DeviceExtensionSize: %lu\n", HwInitializationData
->DeviceExtensionSize
);
755 DPRINT1("SpecificLuExtensionSize: %lu\n", HwInitializationData
->SpecificLuExtensionSize
);
756 DPRINT1("SrbExtensionSize: %lu\n", HwInitializationData
->SrbExtensionSize
);
757 DPRINT1("NumberOfAccessRanges: %lu\n", HwInitializationData
->NumberOfAccessRanges
);
759 /* Check parameters */
760 if ((DriverObject
== NULL
) ||
761 (RegistryPath
== NULL
) ||
762 (HwInitializationData
== NULL
))
764 DPRINT1("Invalid parameter!\n");
765 return STATUS_INVALID_PARAMETER
;
768 /* Check initialization data */
769 if ((HwInitializationData
->HwInitializationDataSize
< sizeof(HW_INITIALIZATION_DATA
)) ||
770 (HwInitializationData
->HwInitialize
== NULL
) ||
771 (HwInitializationData
->HwStartIo
== NULL
) ||
772 (HwInitializationData
->HwFindAdapter
== NULL
) ||
773 (HwInitializationData
->HwResetBus
== NULL
))
775 DPRINT1("Revision mismatch!\n");
776 return STATUS_REVISION_MISMATCH
;
779 DriverObjectExtension
= IoGetDriverObjectExtension(DriverObject
,
781 if (DriverObjectExtension
== NULL
)
783 DPRINT1("No driver object extension!\n");
785 Status
= IoAllocateDriverObjectExtension(DriverObject
,
787 sizeof(DRIVER_OBJECT_EXTENSION
),
788 (PVOID
*)&DriverObjectExtension
);
789 if (!NT_SUCCESS(Status
))
791 DPRINT1("IoAllocateDriverObjectExtension() failed (Status 0x%08lx)\n", Status
);
795 DPRINT1("Driver object extension created!\n");
797 /* Initialize the driver object extension */
798 RtlZeroMemory(DriverObjectExtension
,
799 sizeof(DRIVER_OBJECT_EXTENSION
));
801 DriverObjectExtension
->ExtensionType
= DriverExtension
;
802 DriverObjectExtension
->DriverObject
= DriverObject
;
804 InitializeListHead(&DriverObjectExtension
->AdapterListHead
);
805 KeInitializeSpinLock(&DriverObjectExtension
->AdapterListLock
);
807 InitializeListHead(&DriverObjectExtension
->InitDataListHead
);
810 DriverObject
->DriverExtension
->AddDevice
= PortAddDevice
;
811 // DriverObject->DriverStartIo = PortStartIo;
812 DriverObject
->DriverUnload
= PortUnload
;
813 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = PortDispatchCreate
;
814 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = PortDispatchClose
;
815 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = PortDispatchDeviceControl
;
816 DriverObject
->MajorFunction
[IRP_MJ_SCSI
] = PortDispatchScsi
;
817 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = PortDispatchPower
;
818 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = PortDispatchSystemControl
;
819 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = PortDispatchPnp
;
822 /* Add the initialzation data to the driver extension */
823 Status
= PortAddDriverInitData(DriverObjectExtension
,
824 HwInitializationData
);
826 DPRINT1("StorPortInitialize() done (Status 0x%08lx)\n", Status
);
839 _In_ PVOID HwDeviceExtension
,
840 _In_opt_ PSCSI_REQUEST_BLOCK Srb
,
844 _In_ ULONG ErrorCode
,
847 DPRINT1("ScsiPortLogError() called\n");
848 DPRINT1("PathId: 0x%02x TargetId: 0x%02x Lun: 0x%02x ErrorCode: 0x%08lx UniqueId: 0x%08lx\n",
849 PathId
, TargetId
, Lun
, ErrorCode
, UniqueId
);
851 DPRINT1("ScsiPortLogError() done\n");
862 _Out_writes_bytes_(Length
) PVOID Destination
,
863 _In_reads_bytes_(Length
) PVOID Source
,
866 RtlMoveMemory(Destination
, Source
, Length
);
875 StorPortNotification(
876 _In_ SCSI_NOTIFICATION_TYPE NotificationType
,
877 _In_ PVOID HwDeviceExtension
,
880 DPRINT1("StorPortNotification()\n");
891 _In_ PVOID HwDeviceExtension
,
894 DPRINT1("StorPortPause()\n");
907 _In_ PVOID HwDeviceExtension
,
913 DPRINT1("StorPortPauseDevice()\n");
926 _In_ PVOID HwDeviceExtension
)
928 DPRINT1("StorPortReady()\n");
940 StorPortRegistryRead(
941 _In_ PVOID HwDeviceExtension
,
942 _In_ PUCHAR ValueName
,
946 _In_ PULONG BufferLength
)
948 DPRINT1("StorPortRegistryRead()\n");
960 StorPortRegistryWrite(
961 _In_ PVOID HwDeviceExtension
,
962 _In_ PUCHAR ValueName
,
966 _In_ ULONG BufferLength
)
968 DPRINT1("StorPortRegistryWrite()\n");
981 _In_ PVOID HwDeviceExtension
)
983 DPRINT1("StorPortResume()\n");
995 StorPortResumeDevice(
996 _In_ PVOID HwDeviceExtension
,
1001 DPRINT1("StorPortResumeDevice()\n");
1013 StorPortSetBusDataByOffset(
1014 _In_ PVOID DeviceExtension
,
1015 _In_ ULONG BusDataType
,
1016 _In_ ULONG SystemIoBusNumber
,
1017 _In_ ULONG SlotNumber
,
1018 _In_reads_bytes_(Length
) PVOID Buffer
,
1022 DPRINT1("StorPortSetBusDataByOffset()\n");
1034 StorPortSetDeviceQueueDepth(
1035 _In_ PVOID HwDeviceExtension
,
1037 _In_ UCHAR TargetId
,
1041 DPRINT1("StorPortSetDeviceQueueDepth()\n");
1053 StorPortStallExecution(
1056 KeStallExecutionProcessor(Delay
);
1066 StorPortSynchronizeAccess(
1067 _In_ PVOID HwDeviceExtension
,
1068 _In_ PSTOR_SYNCHRONIZED_ACCESS SynchronizedAccessRoutine
,
1069 _In_opt_ PVOID Context
)
1071 DPRINT1("StorPortSynchronizeAccess()\n");
1082 StorPortValidateRange(
1083 _In_ PVOID HwDeviceExtension
,
1084 _In_ INTERFACE_TYPE BusType
,
1085 _In_ ULONG SystemIoBusNumber
,
1086 _In_ STOR_PHYSICAL_ADDRESS IoAddress
,
1087 _In_ ULONG NumberOfBytes
,
1088 _In_ BOOLEAN InIoSpace
)
1090 DPRINT1("StorPortValidateRange()\n");