mirror of
https://github.com/reactos/reactos.git
synced 2024-09-19 01:00:51 +00:00
b22c128070
CORE-13866
1170 lines
26 KiB
C
1170 lines
26 KiB
C
/*
|
|
* PROJECT: ReactOS Storport Driver
|
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
|
* PURPOSE: Storport driver main file
|
|
* COPYRIGHT: Copyright 2017 Eric Kohl (eric.kohl@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include "precomp.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
ULONG PortNumber = 0;
|
|
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
static
|
|
NTSTATUS
|
|
PortAddDriverInitData(
|
|
PDRIVER_OBJECT_EXTENSION DriverExtension,
|
|
PHW_INITIALIZATION_DATA HwInitializationData)
|
|
{
|
|
PDRIVER_INIT_DATA InitData;
|
|
|
|
DPRINT1("PortAddDriverInitData()\n");
|
|
|
|
InitData = ExAllocatePoolWithTag(NonPagedPool,
|
|
sizeof(DRIVER_INIT_DATA),
|
|
TAG_INIT_DATA);
|
|
if (InitData == NULL)
|
|
return STATUS_NO_MEMORY;
|
|
|
|
RtlCopyMemory(&InitData->HwInitData,
|
|
HwInitializationData,
|
|
sizeof(HW_INITIALIZATION_DATA));
|
|
|
|
InsertHeadList(&DriverExtension->InitDataListHead,
|
|
&InitData->Entry);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
PortDeleteDriverInitData(
|
|
PDRIVER_OBJECT_EXTENSION DriverExtension)
|
|
{
|
|
PDRIVER_INIT_DATA InitData;
|
|
PLIST_ENTRY ListEntry;
|
|
|
|
DPRINT1("PortDeleteDriverInitData()\n");
|
|
|
|
ListEntry = DriverExtension->InitDataListHead.Flink;
|
|
while (ListEntry != &DriverExtension->InitDataListHead)
|
|
{
|
|
InitData = CONTAINING_RECORD(ListEntry,
|
|
DRIVER_INIT_DATA,
|
|
Entry);
|
|
|
|
RemoveEntryList(&InitData->Entry);
|
|
|
|
ExFreePoolWithTag(InitData,
|
|
TAG_INIT_DATA);
|
|
|
|
ListEntry = DriverExtension->InitDataListHead.Flink;
|
|
}
|
|
}
|
|
|
|
|
|
PHW_INITIALIZATION_DATA
|
|
PortGetDriverInitData(
|
|
PDRIVER_OBJECT_EXTENSION DriverExtension,
|
|
INTERFACE_TYPE InterfaceType)
|
|
{
|
|
PDRIVER_INIT_DATA InitData;
|
|
PLIST_ENTRY ListEntry;
|
|
|
|
DPRINT1("PortGetDriverInitData()\n");
|
|
|
|
ListEntry = DriverExtension->InitDataListHead.Flink;
|
|
while (ListEntry != &DriverExtension->InitDataListHead)
|
|
{
|
|
InitData = CONTAINING_RECORD(ListEntry,
|
|
DRIVER_INIT_DATA,
|
|
Entry);
|
|
if (InitData->HwInitData.AdapterInterfaceType == InterfaceType)
|
|
return &InitData->HwInitData;
|
|
|
|
ListEntry = ListEntry->Flink;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static
|
|
NTSTATUS
|
|
NTAPI
|
|
PortAddDevice(
|
|
_In_ PDRIVER_OBJECT DriverObject,
|
|
_In_ PDEVICE_OBJECT PhysicalDeviceObject)
|
|
{
|
|
PDRIVER_OBJECT_EXTENSION DriverObjectExtension;
|
|
PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
|
|
WCHAR NameBuffer[80];
|
|
UNICODE_STRING DeviceName;
|
|
PDEVICE_OBJECT Fdo = NULL;
|
|
KLOCK_QUEUE_HANDLE LockHandle;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT1("PortAddDevice(%p %p)\n",
|
|
DriverObject, PhysicalDeviceObject);
|
|
|
|
ASSERT(DriverObject);
|
|
ASSERT(PhysicalDeviceObject);
|
|
|
|
swprintf(NameBuffer,
|
|
L"\\Device\\RaidPort%lu",
|
|
PortNumber);
|
|
RtlInitUnicodeString(&DeviceName, NameBuffer);
|
|
PortNumber++;
|
|
|
|
DPRINT1("Creating device: %wZ\n", &DeviceName);
|
|
|
|
/* Create the port device */
|
|
Status = IoCreateDevice(DriverObject,
|
|
sizeof(FDO_DEVICE_EXTENSION),
|
|
&DeviceName,
|
|
FILE_DEVICE_CONTROLLER,
|
|
FILE_DEVICE_SECURE_OPEN,
|
|
FALSE,
|
|
&Fdo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("IoCreateDevice() failed (Status 0x%08lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
DPRINT1("Created device: %wZ (%p)\n", &DeviceName, Fdo);
|
|
|
|
/* Initialize the device */
|
|
Fdo->Flags |= DO_DIRECT_IO;
|
|
Fdo->Flags |= DO_POWER_PAGABLE;
|
|
|
|
/* Initialize the device extension */
|
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
|
|
RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
|
|
|
|
DeviceExtension->ExtensionType = FdoExtension;
|
|
|
|
DeviceExtension->Device = Fdo;
|
|
DeviceExtension->PhysicalDevice = PhysicalDeviceObject;
|
|
|
|
DeviceExtension->PnpState = dsStopped;
|
|
|
|
/* Attach the FDO to the device stack */
|
|
Status = IoAttachDeviceToDeviceStackSafe(Fdo,
|
|
PhysicalDeviceObject,
|
|
&DeviceExtension->LowerDevice);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("IoAttachDeviceToDeviceStackSafe() failed (Status 0x%08lx)\n", Status);
|
|
IoDeleteDevice(Fdo);
|
|
return Status;
|
|
}
|
|
|
|
/* Insert the FDO to the drivers FDO list */
|
|
DriverObjectExtension = IoGetDriverObjectExtension(DriverObject,
|
|
(PVOID)DriverEntry);
|
|
ASSERT(DriverObjectExtension->ExtensionType == DriverExtension);
|
|
|
|
DeviceExtension->DriverExtension = DriverObjectExtension;
|
|
|
|
KeAcquireInStackQueuedSpinLock(&DriverObjectExtension->AdapterListLock,
|
|
&LockHandle);
|
|
|
|
InsertHeadList(&DriverObjectExtension->AdapterListHead,
|
|
&DeviceExtension->AdapterListEntry);
|
|
DriverObjectExtension->AdapterCount++;
|
|
|
|
KeReleaseInStackQueuedSpinLock(&LockHandle);
|
|
|
|
/* The device has been initialized */
|
|
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
|
|
|
DPRINT1("PortAddDevice() done (Status 0x%08lx)\n", Status);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
NTAPI
|
|
PortUnload(
|
|
_In_ PDRIVER_OBJECT DriverObject)
|
|
{
|
|
PDRIVER_OBJECT_EXTENSION DriverExtension;
|
|
|
|
DPRINT1("PortUnload(%p)\n",
|
|
DriverObject);
|
|
|
|
DriverExtension = IoGetDriverObjectExtension(DriverObject,
|
|
(PVOID)DriverEntry);
|
|
if (DriverExtension != NULL)
|
|
{
|
|
PortDeleteDriverInitData(DriverExtension);
|
|
}
|
|
}
|
|
|
|
|
|
static
|
|
NTSTATUS
|
|
NTAPI
|
|
PortDispatchCreate(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
DPRINT1("PortDispatchCreate(%p %p)\n",
|
|
DeviceObject, Irp);
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = FILE_OPENED;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
static
|
|
NTSTATUS
|
|
NTAPI
|
|
PortDispatchClose(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
DPRINT1("PortDispatchClose(%p %p)\n",
|
|
DeviceObject, Irp);
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
static
|
|
NTSTATUS
|
|
NTAPI
|
|
PortDispatchDeviceControl(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
DPRINT1("PortDispatchDeviceControl(%p %p)\n",
|
|
DeviceObject, Irp);
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
static
|
|
NTSTATUS
|
|
NTAPI
|
|
PortDispatchScsi(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
DPRINT1("PortDispatchScsi(%p %p)\n",
|
|
DeviceObject, Irp);
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
static
|
|
NTSTATUS
|
|
NTAPI
|
|
PortDispatchSystemControl(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
DPRINT1("PortDispatchSystemControl(%p %p)\n",
|
|
DeviceObject, Irp);
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
static
|
|
NTSTATUS
|
|
NTAPI
|
|
PortDispatchPnp(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
DPRINT1("PortDispatchPnp(%p %p)\n",
|
|
DeviceObject, Irp);
|
|
|
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
DPRINT1("ExtensionType: %u\n", DeviceExtension->ExtensionType);
|
|
|
|
switch (DeviceExtension->ExtensionType)
|
|
{
|
|
case FdoExtension:
|
|
return PortFdoPnp(DeviceObject,
|
|
Irp);
|
|
|
|
case PdoExtension:
|
|
return PortPdoPnp(DeviceObject,
|
|
Irp);
|
|
|
|
default:
|
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
}
|
|
|
|
|
|
static
|
|
NTSTATUS
|
|
NTAPI
|
|
PortDispatchPower(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
DPRINT1("PortDispatchPower(%p %p)\n",
|
|
DeviceObject, Irp);
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
NTSTATUS
|
|
NTAPI
|
|
DriverEntry(
|
|
_In_ PDRIVER_OBJECT DriverObject,
|
|
_In_ PUNICODE_STRING RegistryPath)
|
|
{
|
|
DPRINT1("DriverEntry(%p %p)\n", DriverObject, RegistryPath);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
PUCHAR
|
|
NTAPI
|
|
StorPortAllocateRegistryBuffer(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ PULONG Length)
|
|
{
|
|
DPRINT1("StorPortAllocateRegistryBuffer()\n");
|
|
UNIMPLEMENTED;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortBusy(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ ULONG RequestsToComplete)
|
|
{
|
|
DPRINT1("StorPortBuzy()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
VOID
|
|
NTAPI
|
|
StorPortCompleteRequest(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ UCHAR PathId,
|
|
_In_ UCHAR TargetId,
|
|
_In_ UCHAR Lun,
|
|
_In_ UCHAR SrbStatus)
|
|
{
|
|
DPRINT1("StorPortCompleteRequest()\n");
|
|
UNIMPLEMENTED;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
ULONG
|
|
NTAPI
|
|
StorPortConvertPhysicalAddressToUlong(
|
|
_In_ STOR_PHYSICAL_ADDRESS Address)
|
|
{
|
|
DPRINT1("StorPortConvertPhysicalAddressToUlong()\n");
|
|
|
|
return Address.u.LowPart;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
STOR_PHYSICAL_ADDRESS
|
|
NTAPI
|
|
StorPortConvertUlongToPhysicalAddress(
|
|
_In_ ULONG_PTR UlongAddress)
|
|
{
|
|
STOR_PHYSICAL_ADDRESS Address;
|
|
|
|
DPRINT1("StorPortConvertUlongToPhysicalAddress()\n");
|
|
|
|
Address.QuadPart = UlongAddress;
|
|
return Address;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
VOID
|
|
StorPortDebugPrint(
|
|
_In_ ULONG DebugPrintLevel,
|
|
_In_ PCHAR DebugMessage,
|
|
...)
|
|
{
|
|
va_list ap;
|
|
|
|
va_start(ap, DebugMessage);
|
|
vDbgPrintExWithPrefix("STORMINI: ", 0x58, DebugPrintLevel, DebugMessage, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortDeviceBusy(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ UCHAR PathId,
|
|
_In_ UCHAR TargetId,
|
|
_In_ UCHAR Lun,
|
|
_In_ ULONG RequestsToComplete)
|
|
{
|
|
DPRINT1("StorPortDeviceBusy()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortDeviceReady(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ UCHAR PathId,
|
|
_In_ UCHAR TargetId,
|
|
_In_ UCHAR Lun)
|
|
{
|
|
DPRINT1("StorPortDeviceReady()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
VOID
|
|
NTAPI
|
|
StorPortFreeDeviceBase(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ PVOID MappedAddress)
|
|
{
|
|
DPRINT1("StorPortFreeDeviceBase(%p %p)\n",
|
|
HwDeviceExtension, MappedAddress);
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
VOID
|
|
NTAPI
|
|
StorPortFreeRegistryBuffer(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ PUCHAR Buffer)
|
|
{
|
|
DPRINT1("StorPortFreeRegistryBuffer()\n");
|
|
UNIMPLEMENTED;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
ULONG
|
|
NTAPI
|
|
StorPortGetBusData(
|
|
_In_ PVOID DeviceExtension,
|
|
_In_ ULONG BusDataType,
|
|
_In_ ULONG SystemIoBusNumber,
|
|
_In_ ULONG SlotNumber,
|
|
_Out_ _When_(Length != 0, _Out_writes_bytes_(Length)) PVOID Buffer,
|
|
_In_ ULONG Length)
|
|
{
|
|
PMINIPORT_DEVICE_EXTENSION MiniportExtension;
|
|
PBUS_INTERFACE_STANDARD Interface;
|
|
ULONG ReturnLength;
|
|
|
|
DPRINT1("StorPortGetBusData(%p %lu %lu %lu %p %lu)\n",
|
|
DeviceExtension, BusDataType, SystemIoBusNumber, SlotNumber, Buffer, Length);
|
|
|
|
/* Get the miniport extension */
|
|
MiniportExtension = CONTAINING_RECORD(DeviceExtension,
|
|
MINIPORT_DEVICE_EXTENSION,
|
|
HwDeviceExtension);
|
|
DPRINT1("DeviceExtension %p MiniportExtension %p\n",
|
|
DeviceExtension, MiniportExtension);
|
|
|
|
Interface = &MiniportExtension->Miniport->DeviceExtension->BusInterface;
|
|
|
|
if (BusDataType == 4)
|
|
BusDataType = 0;
|
|
|
|
ReturnLength = Interface->GetBusData(Interface->Context,
|
|
BusDataType,
|
|
Buffer,
|
|
0,
|
|
Length);
|
|
DPRINT1("ReturnLength: %lu\n", ReturnLength);
|
|
|
|
return ReturnLength;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
PVOID
|
|
NTAPI
|
|
StorPortGetDeviceBase(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ INTERFACE_TYPE BusType,
|
|
_In_ ULONG SystemIoBusNumber,
|
|
_In_ STOR_PHYSICAL_ADDRESS IoAddress,
|
|
_In_ ULONG NumberOfBytes,
|
|
_In_ BOOLEAN InIoSpace)
|
|
{
|
|
PMINIPORT_DEVICE_EXTENSION MiniportExtension;
|
|
|
|
PHYSICAL_ADDRESS TranslatedAddress;
|
|
PVOID MappedAddress;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT1("StorPortGetDeviceBase(%p %lu %lu 0x%I64x %lu %u)\n",
|
|
HwDeviceExtension, BusType, SystemIoBusNumber, IoAddress.QuadPart, NumberOfBytes, InIoSpace);
|
|
|
|
/* Get the miniport extension */
|
|
MiniportExtension = CONTAINING_RECORD(HwDeviceExtension,
|
|
MINIPORT_DEVICE_EXTENSION,
|
|
HwDeviceExtension);
|
|
DPRINT1("HwDeviceExtension %p MiniportExtension %p\n",
|
|
HwDeviceExtension, MiniportExtension);
|
|
|
|
if (!TranslateResourceListAddress(MiniportExtension->Miniport->DeviceExtension,
|
|
BusType,
|
|
SystemIoBusNumber,
|
|
IoAddress,
|
|
NumberOfBytes,
|
|
InIoSpace,
|
|
&TranslatedAddress))
|
|
{
|
|
DPRINT1("Checkpoint!\n");
|
|
return NULL;
|
|
}
|
|
|
|
DPRINT1("Translated Address: 0x%I64x\n", TranslatedAddress.QuadPart);
|
|
|
|
/* In I/O space */
|
|
if (InIoSpace)
|
|
{
|
|
DPRINT1("Translated Address: %p\n", (PVOID)(ULONG_PTR)TranslatedAddress.QuadPart);
|
|
return (PVOID)(ULONG_PTR)TranslatedAddress.QuadPart;
|
|
}
|
|
|
|
/* In memory space */
|
|
MappedAddress = MmMapIoSpace(TranslatedAddress,
|
|
NumberOfBytes,
|
|
FALSE);
|
|
DPRINT1("Mapped Address: %p\n", MappedAddress);
|
|
|
|
Status = AllocateAddressMapping(&MiniportExtension->Miniport->DeviceExtension->MappedAddressList,
|
|
IoAddress,
|
|
MappedAddress,
|
|
NumberOfBytes,
|
|
SystemIoBusNumber);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("Checkpoint!\n");
|
|
MappedAddress = NULL;
|
|
}
|
|
|
|
DPRINT1("Mapped Address: %p\n", MappedAddress);
|
|
return MappedAddress;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
PVOID
|
|
NTAPI
|
|
StorPortGetLogicalUnit(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ UCHAR PathId,
|
|
_In_ UCHAR TargetId,
|
|
_In_ UCHAR Lun)
|
|
{
|
|
DPRINT1("StorPortGetLogicalUnit()\n");
|
|
UNIMPLEMENTED;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
STOR_PHYSICAL_ADDRESS
|
|
NTAPI
|
|
StorPortGetPhysicalAddress(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_opt_ PSCSI_REQUEST_BLOCK Srb,
|
|
_In_ PVOID VirtualAddress,
|
|
_Out_ ULONG *Length)
|
|
{
|
|
STOR_PHYSICAL_ADDRESS PhysicalAddress;
|
|
|
|
DPRINT1("StorPortGetPhysicalAddress(%p %p %p %p)\n",
|
|
HwDeviceExtension, Srb, VirtualAddress, Length);
|
|
UNIMPLEMENTED;
|
|
|
|
*Length = 0;
|
|
PhysicalAddress.QuadPart = (LONGLONG)0;
|
|
|
|
return PhysicalAddress;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
PSTOR_SCATTER_GATHER_LIST
|
|
NTAPI
|
|
StorPortGetScatterGatherList(
|
|
_In_ PVOID DeviceExtension,
|
|
_In_ PSCSI_REQUEST_BLOCK Srb)
|
|
{
|
|
DPRINT1("StorPortGetScatterGatherList()\n");
|
|
UNIMPLEMENTED;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
PSCSI_REQUEST_BLOCK
|
|
NTAPI
|
|
StorPortGetSrb(
|
|
_In_ PVOID DeviceExtension,
|
|
_In_ UCHAR PathId,
|
|
_In_ UCHAR TargetId,
|
|
_In_ UCHAR Lun,
|
|
_In_ LONG QueueTag)
|
|
{
|
|
DPRINT("StorPortGetSrb()\n");
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
PVOID
|
|
NTAPI
|
|
StorPortGetUncachedExtension(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
|
_In_ ULONG NumberOfBytes)
|
|
{
|
|
DPRINT1("StorPortGetUncachedExtension(%p %p %lu)\n",
|
|
HwDeviceExtension, ConfigInfo, NumberOfBytes);
|
|
UNIMPLEMENTED;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
PVOID
|
|
NTAPI
|
|
StorPortGetVirtualAddress(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ STOR_PHYSICAL_ADDRESS PhysicalAddress)
|
|
{
|
|
DPRINT1("StorPortGetVirtualAddress(%p %I64x)\n",
|
|
HwDeviceExtension, PhysicalAddress.QuadPart);
|
|
UNIMPLEMENTED;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
ULONG
|
|
NTAPI
|
|
StorPortInitialize(
|
|
_In_ PVOID Argument1,
|
|
_In_ PVOID Argument2,
|
|
_In_ struct _HW_INITIALIZATION_DATA *HwInitializationData,
|
|
_In_opt_ PVOID HwContext)
|
|
{
|
|
PDRIVER_OBJECT DriverObject = (PDRIVER_OBJECT)Argument1;
|
|
PUNICODE_STRING RegistryPath = (PUNICODE_STRING)Argument2;
|
|
PDRIVER_OBJECT_EXTENSION DriverObjectExtension;
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
DPRINT1("StorPortInitialize(%p %p %p %p)\n",
|
|
Argument1, Argument2, HwInitializationData, HwContext);
|
|
|
|
DPRINT1("HwInitializationDataSize: %lu\n", HwInitializationData->HwInitializationDataSize);
|
|
DPRINT1("AdapterInterfaceType: %u\n", HwInitializationData->AdapterInterfaceType);
|
|
DPRINT1("HwInitialize: %p\n", HwInitializationData->HwInitialize);
|
|
DPRINT1("HwStartIo: %p\n", HwInitializationData->HwStartIo);
|
|
DPRINT1("HwInterrupt: %p\n", HwInitializationData->HwInterrupt);
|
|
DPRINT1("HwFindAdapter: %p\n", HwInitializationData->HwFindAdapter);
|
|
DPRINT1("HwResetBus: %p\n", HwInitializationData->HwResetBus);
|
|
DPRINT1("HwDmaStarted: %p\n", HwInitializationData->HwDmaStarted);
|
|
DPRINT1("HwAdapterState: %p\n", HwInitializationData->HwAdapterState);
|
|
DPRINT1("DeviceExtensionSize: %lu\n", HwInitializationData->DeviceExtensionSize);
|
|
DPRINT1("SpecificLuExtensionSize: %lu\n", HwInitializationData->SpecificLuExtensionSize);
|
|
DPRINT1("SrbExtensionSize: %lu\n", HwInitializationData->SrbExtensionSize);
|
|
DPRINT1("NumberOfAccessRanges: %lu\n", HwInitializationData->NumberOfAccessRanges);
|
|
|
|
/* Check parameters */
|
|
if ((DriverObject == NULL) ||
|
|
(RegistryPath == NULL) ||
|
|
(HwInitializationData == NULL))
|
|
{
|
|
DPRINT1("Invalid parameter!\n");
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
/* Check initialization data */
|
|
if ((HwInitializationData->HwInitializationDataSize < sizeof(HW_INITIALIZATION_DATA)) ||
|
|
(HwInitializationData->HwInitialize == NULL) ||
|
|
(HwInitializationData->HwStartIo == NULL) ||
|
|
(HwInitializationData->HwFindAdapter == NULL) ||
|
|
(HwInitializationData->HwResetBus == NULL))
|
|
{
|
|
DPRINT1("Revision mismatch!\n");
|
|
return STATUS_REVISION_MISMATCH;
|
|
}
|
|
|
|
DriverObjectExtension = IoGetDriverObjectExtension(DriverObject,
|
|
(PVOID)DriverEntry);
|
|
if (DriverObjectExtension == NULL)
|
|
{
|
|
DPRINT1("No driver object extension!\n");
|
|
|
|
Status = IoAllocateDriverObjectExtension(DriverObject,
|
|
(PVOID)DriverEntry,
|
|
sizeof(DRIVER_OBJECT_EXTENSION),
|
|
(PVOID *)&DriverObjectExtension);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("IoAllocateDriverObjectExtension() failed (Status 0x%08lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
DPRINT1("Driver object extension created!\n");
|
|
|
|
/* Initialize the driver object extension */
|
|
RtlZeroMemory(DriverObjectExtension,
|
|
sizeof(DRIVER_OBJECT_EXTENSION));
|
|
|
|
DriverObjectExtension->ExtensionType = DriverExtension;
|
|
DriverObjectExtension->DriverObject = DriverObject;
|
|
|
|
InitializeListHead(&DriverObjectExtension->AdapterListHead);
|
|
KeInitializeSpinLock(&DriverObjectExtension->AdapterListLock);
|
|
|
|
InitializeListHead(&DriverObjectExtension->InitDataListHead);
|
|
|
|
/* Set handlers */
|
|
DriverObject->DriverExtension->AddDevice = PortAddDevice;
|
|
// DriverObject->DriverStartIo = PortStartIo;
|
|
DriverObject->DriverUnload = PortUnload;
|
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = PortDispatchCreate;
|
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = PortDispatchClose;
|
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PortDispatchDeviceControl;
|
|
DriverObject->MajorFunction[IRP_MJ_SCSI] = PortDispatchScsi;
|
|
DriverObject->MajorFunction[IRP_MJ_POWER] = PortDispatchPower;
|
|
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = PortDispatchSystemControl;
|
|
DriverObject->MajorFunction[IRP_MJ_PNP] = PortDispatchPnp;
|
|
}
|
|
|
|
/* Add the initialzation data to the driver extension */
|
|
Status = PortAddDriverInitData(DriverObjectExtension,
|
|
HwInitializationData);
|
|
|
|
DPRINT1("StorPortInitialize() done (Status 0x%08lx)\n", Status);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
VOID
|
|
NTAPI
|
|
StorPortLogError(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_opt_ PSCSI_REQUEST_BLOCK Srb,
|
|
_In_ UCHAR PathId,
|
|
_In_ UCHAR TargetId,
|
|
_In_ UCHAR Lun,
|
|
_In_ ULONG ErrorCode,
|
|
_In_ ULONG UniqueId)
|
|
{
|
|
DPRINT1("ScsiPortLogError() called\n");
|
|
DPRINT1("PathId: 0x%02x TargetId: 0x%02x Lun: 0x%02x ErrorCode: 0x%08lx UniqueId: 0x%08lx\n",
|
|
PathId, TargetId, Lun, ErrorCode, UniqueId);
|
|
|
|
DPRINT1("ScsiPortLogError() done\n");
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
VOID
|
|
NTAPI
|
|
StorPortMoveMemory(
|
|
_Out_writes_bytes_(Length) PVOID Destination,
|
|
_In_reads_bytes_(Length) PVOID Source,
|
|
_In_ ULONG Length)
|
|
{
|
|
RtlMoveMemory(Destination, Source, Length);
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
VOID
|
|
StorPortNotification(
|
|
_In_ SCSI_NOTIFICATION_TYPE NotificationType,
|
|
_In_ PVOID HwDeviceExtension,
|
|
...)
|
|
{
|
|
DPRINT1("StorPortNotification()\n");
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortPause(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ ULONG TimeOut)
|
|
{
|
|
DPRINT1("StorPortPause()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortPauseDevice(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ UCHAR PathId,
|
|
_In_ UCHAR TargetId,
|
|
_In_ UCHAR Lun,
|
|
_In_ ULONG TimeOut)
|
|
{
|
|
DPRINT1("StorPortPauseDevice()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortReady(
|
|
_In_ PVOID HwDeviceExtension)
|
|
{
|
|
DPRINT1("StorPortReady()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortRegistryRead(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ PUCHAR ValueName,
|
|
_In_ ULONG Global,
|
|
_In_ ULONG Type,
|
|
_In_ PUCHAR Buffer,
|
|
_In_ PULONG BufferLength)
|
|
{
|
|
DPRINT1("StorPortRegistryRead()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortRegistryWrite(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ PUCHAR ValueName,
|
|
_In_ ULONG Global,
|
|
_In_ ULONG Type,
|
|
_In_ PUCHAR Buffer,
|
|
_In_ ULONG BufferLength)
|
|
{
|
|
DPRINT1("StorPortRegistryWrite()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortResume(
|
|
_In_ PVOID HwDeviceExtension)
|
|
{
|
|
DPRINT1("StorPortResume()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortResumeDevice(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ UCHAR PathId,
|
|
_In_ UCHAR TargetId,
|
|
_In_ UCHAR Lun)
|
|
{
|
|
DPRINT1("StorPortResumeDevice()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
ULONG
|
|
NTAPI
|
|
StorPortSetBusDataByOffset(
|
|
_In_ PVOID DeviceExtension,
|
|
_In_ ULONG BusDataType,
|
|
_In_ ULONG SystemIoBusNumber,
|
|
_In_ ULONG SlotNumber,
|
|
_In_reads_bytes_(Length) PVOID Buffer,
|
|
_In_ ULONG Offset,
|
|
_In_ ULONG Length)
|
|
{
|
|
PMINIPORT_DEVICE_EXTENSION MiniportExtension;
|
|
PBUS_INTERFACE_STANDARD Interface;
|
|
ULONG ReturnLength;
|
|
|
|
DPRINT1("StorPortSetBusData(%p %lu %lu %lu %p %lu %lu)\n",
|
|
DeviceExtension, BusDataType, SystemIoBusNumber, SlotNumber, Buffer, Offset, Length);
|
|
|
|
MiniportExtension = CONTAINING_RECORD(DeviceExtension,
|
|
MINIPORT_DEVICE_EXTENSION,
|
|
HwDeviceExtension);
|
|
DPRINT1("DeviceExtension %p MiniportExtension %p\n",
|
|
DeviceExtension, MiniportExtension);
|
|
|
|
Interface = &MiniportExtension->Miniport->DeviceExtension->BusInterface;
|
|
|
|
ReturnLength = Interface->SetBusData(Interface->Context,
|
|
BusDataType,
|
|
Buffer,
|
|
Offset,
|
|
Length);
|
|
DPRINT1("ReturnLength: %lu\n", ReturnLength);
|
|
|
|
return ReturnLength;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortSetDeviceQueueDepth(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ UCHAR PathId,
|
|
_In_ UCHAR TargetId,
|
|
_In_ UCHAR Lun,
|
|
_In_ ULONG Depth)
|
|
{
|
|
DPRINT1("StorPortSetDeviceQueueDepth()\n");
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
VOID
|
|
NTAPI
|
|
StorPortStallExecution(
|
|
_In_ ULONG Delay)
|
|
{
|
|
KeStallExecutionProcessor(Delay);
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
STORPORT_API
|
|
VOID
|
|
NTAPI
|
|
StorPortSynchronizeAccess(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ PSTOR_SYNCHRONIZED_ACCESS SynchronizedAccessRoutine,
|
|
_In_opt_ PVOID Context)
|
|
{
|
|
DPRINT1("StorPortSynchronizeAccess()\n");
|
|
UNIMPLEMENTED;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
STORPORT_API
|
|
BOOLEAN
|
|
NTAPI
|
|
StorPortValidateRange(
|
|
_In_ PVOID HwDeviceExtension,
|
|
_In_ INTERFACE_TYPE BusType,
|
|
_In_ ULONG SystemIoBusNumber,
|
|
_In_ STOR_PHYSICAL_ADDRESS IoAddress,
|
|
_In_ ULONG NumberOfBytes,
|
|
_In_ BOOLEAN InIoSpace)
|
|
{
|
|
DPRINT1("StorPortValidateRange()\n");
|
|
return TRUE;
|
|
}
|
|
|
|
/* EOF */
|