https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f7c01906e7d81173d2714…
commit f7c01906e7d81173d271456a179c74ecc68aeb28
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Thu May 24 11:39:01 2018 +0200
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Thu May 24 11:39:47 2018 +0200
[STORPORT] Enumerate attached devices
- Implement AcquireSpinlock, ReleaseSpinlock and GetExtendedFunctionTable
notifications.
- Implement a bus scan routine, borrowed from scsiport.
Storport and storahci are now able to detect a disk device attached to a Virtual Box
AHCI controller.
---
drivers/storage/port/storport/fdo.c | 314 ++++++++++++++++++++++++++++
drivers/storage/port/storport/miniport.c | 17 ++
drivers/storage/port/storport/misc.c | 13 --
drivers/storage/port/storport/pdo.c | 15 ++
drivers/storage/port/storport/precomp.h | 19 ++
drivers/storage/port/storport/storport.c | 148 ++++++++++++-
drivers/storage/port/storport/storport.spec | 4 +-
sdk/include/ddk/storport.h | 73 ++++++-
8 files changed, 581 insertions(+), 22 deletions(-)
diff --git a/drivers/storage/port/storport/fdo.c b/drivers/storage/port/storport/fdo.c
index 92a5a7f9a1..e20fd68bcc 100644
--- a/drivers/storage/port/storport/fdo.c
+++ b/drivers/storage/port/storport/fdo.c
@@ -243,6 +243,289 @@ PortFdoStartDevice(
}
+static NTSTATUS
+SpiSendInquiry(IN PDEVICE_OBJECT DeviceObject,
+ ULONG Bus, ULONG Target, ULONG Lun)
+{
+// IO_STATUS_BLOCK IoStatusBlock;
+// PIO_STACK_LOCATION IrpStack;
+// KEVENT Event;
+// KIRQL Irql;
+// PIRP Irp;
+ NTSTATUS Status;
+ PINQUIRYDATA InquiryBuffer;
+ PUCHAR /*PSENSE_DATA*/ SenseBuffer;
+// BOOLEAN KeepTrying = TRUE;
+// ULONG RetryCount = 0;
+ SCSI_REQUEST_BLOCK Srb;
+ PCDB Cdb;
+// PSCSI_PORT_LUN_EXTENSION LunExtension;
+// PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+
+PFDO_DEVICE_EXTENSION DeviceExtension;
+ PVOID SrbExtension = NULL;
+ BOOLEAN ret;
+
+ DPRINT1("SpiSendInquiry() called\n");
+
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ InquiryBuffer = ExAllocatePoolWithTag(NonPagedPool, INQUIRYDATABUFFERSIZE,
TAG_INQUIRY_DATA);
+ if (InquiryBuffer == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ SenseBuffer = ExAllocatePoolWithTag(NonPagedPool, SENSE_BUFFER_SIZE,
TAG_SENSE_DATA);
+ if (SenseBuffer == NULL)
+ {
+ ExFreePoolWithTag(InquiryBuffer, TAG_INQUIRY_DATA);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if (DeviceExtension->Miniport.PortConfig.SrbExtensionSize != 0)
+ {
+ SrbExtension = ExAllocatePoolWithTag(NonPagedPool,
DeviceExtension->Miniport.PortConfig.SrbExtensionSize, TAG_SENSE_DATA);
+ if (SrbExtension == NULL)
+ {
+ ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA);
+ ExFreePoolWithTag(InquiryBuffer, TAG_INQUIRY_DATA);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+// while (KeepTrying)
+ {
+ /* Initialize event for waiting */
+// KeInitializeEvent(&Event,
+// NotificationEvent,
+// FALSE);
+
+ /* Create an IRP */
+// Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_EXECUTE_IN,
+// DeviceObject,
+// NULL,
+// 0,
+// InquiryBuffer,
+// INQUIRYDATABUFFERSIZE,
+// TRUE,
+// &Event,
+// &IoStatusBlock);
+// if (Irp == NULL)
+// {
+// DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
+
+ /* Quit the loop */
+// Status = STATUS_INSUFFICIENT_RESOURCES;
+// KeepTrying = FALSE;
+// continue;
+// }
+
+ /* Prepare SRB */
+ RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
+
+ Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
+// Srb.OriginalRequest = Irp;
+ Srb.PathId = Bus;
+ Srb.TargetId = Target;
+ Srb.Lun = Lun;
+ Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
+ Srb.SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
+ Srb.TimeOutValue = 4;
+ Srb.CdbLength = 6;
+
+ Srb.SenseInfoBuffer = SenseBuffer;
+ Srb.SenseInfoBufferLength = SENSE_BUFFER_SIZE;
+
+ Srb.DataBuffer = InquiryBuffer;
+ Srb.DataTransferLength = INQUIRYDATABUFFERSIZE;
+
+ Srb.SrbExtension = SrbExtension;
+
+ /* Attach Srb to the Irp */
+// IrpStack = IoGetNextIrpStackLocation(Irp);
+// IrpStack->Parameters.Scsi.Srb = &Srb;
+
+ /* Fill in CDB */
+ Cdb = (PCDB)Srb.Cdb;
+ Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
+ Cdb->CDB6INQUIRY.LogicalUnitNumber = Lun;
+ Cdb->CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE;
+
+ /* Call the driver */
+
+
+ ret = MiniportStartIo(&DeviceExtension->Miniport,
+ &Srb);
+DPRINT1("MiniportStartIo returned %u\n", ret);
+
+// Status = IoCallDriver(DeviceObject, Irp);
+
+ /* Wait for it to complete */
+// if (Status == STATUS_PENDING)
+// {
+// DPRINT1("SpiSendInquiry(): Waiting for the driver to process
request...\n");
+// KeWaitForSingleObject(&Event,
+// Executive,
+// KernelMode,
+// FALSE,
+// NULL);
+// Status = IoStatusBlock.Status;
+// }
+
+// DPRINT1("SpiSendInquiry(): Request processed by driver, status =
0x%08X\n", Status);
+
+ if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_SUCCESS)
+ {
+ /* All fine, copy data over */
+// RtlCopyMemory(LunInfo->InquiryData,
+// InquiryBuffer,
+// INQUIRYDATABUFFERSIZE);
+
+ /* Quit the loop */
+ Status = STATUS_SUCCESS;
+// KeepTrying = FALSE;
+// continue;
+ }
+
+ DPRINT("Inquiry SRB failed with SrbStatus 0x%08X\n", Srb.SrbStatus);
+#if 0
+ /* Check if the queue is frozen */
+ if (Srb.SrbStatus & SRB_STATUS_QUEUE_FROZEN)
+ {
+ /* Something weird happened, deal with it (unfreeze the queue) */
+ KeepTrying = FALSE;
+
+ DPRINT("SpiSendInquiry(): the queue is frozen at TargetId %d\n",
Srb.TargetId);
+
+ LunExtension = SpiGetLunExtension(DeviceExtension,
+ LunInfo->PathId,
+ LunInfo->TargetId,
+ LunInfo->Lun);
+
+ /* Clear frozen flag */
+ LunExtension->Flags &= ~LUNEX_FROZEN_QUEUE;
+
+ /* Acquire the spinlock */
+ KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
+
+ /* Process the request */
+ SpiGetNextRequestFromLun(DeviceObject->DeviceExtension, LunExtension);
+
+ /* SpiGetNextRequestFromLun() releases the spinlock,
+ so we just lower irql back to what it was before */
+ KeLowerIrql(Irql);
+ }
+
+ /* Check if data overrun happened */
+ if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN)
+ {
+ DPRINT("Data overrun at TargetId %d\n", LunInfo->TargetId);
+
+ /* Nothing dramatic, just copy data, but limiting the size */
+ RtlCopyMemory(LunInfo->InquiryData,
+ InquiryBuffer,
+ (Srb.DataTransferLength > INQUIRYDATABUFFERSIZE) ?
+ INQUIRYDATABUFFERSIZE : Srb.DataTransferLength);
+
+ /* Quit the loop */
+ Status = STATUS_SUCCESS;
+ KeepTrying = FALSE;
+ }
+ else if ((Srb.SrbStatus & SRB_STATUS_AUTOSENSE_VALID) &&
+ SenseBuffer->SenseKey == SCSI_SENSE_ILLEGAL_REQUEST)
+ {
+ /* LUN is not valid, but some device responds there.
+ Mark it as invalid anyway */
+
+ /* Quit the loop */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ KeepTrying = FALSE;
+ }
+ else
+ {
+ /* Retry a couple of times if no timeout happened */
+ if ((RetryCount < 2) &&
+ (SRB_STATUS(Srb.SrbStatus) != SRB_STATUS_NO_DEVICE) &&
+ (SRB_STATUS(Srb.SrbStatus) != SRB_STATUS_SELECTION_TIMEOUT))
+ {
+ RetryCount++;
+ KeepTrying = TRUE;
+ }
+ else
+ {
+ /* That's all, quit the loop */
+ KeepTrying = FALSE;
+
+ /* Set status according to SRB status */
+ if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_BAD_FUNCTION ||
+ SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_BAD_SRB_BLOCK_LENGTH)
+ {
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+ else
+ {
+ Status = STATUS_IO_DEVICE_ERROR;
+ }
+ }
+ }
+#endif
+ }
+
+ /* Free buffers */
+ if (SrbExtension != NULL)
+ ExFreePoolWithTag(SrbExtension, TAG_SENSE_DATA);
+
+ ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA);
+ ExFreePoolWithTag(InquiryBuffer, TAG_INQUIRY_DATA);
+
+ DPRINT("SpiSendInquiry() done with Status 0x%08X\n", Status);
+
+ return Status;
+}
+
+
+static
+NTSTATUS
+PortFdoScanBus(
+ _In_ PFDO_DEVICE_EXTENSION DeviceExtension)
+{
+ ULONG Bus, Target, Lun;
+ NTSTATUS Status;
+
+
+ DPRINT1("PortFdoScanBus(%p)\n",
+ DeviceExtension);
+
+ DPRINT1("NumberOfBuses: %lu\n",
DeviceExtension->Miniport.PortConfig.NumberOfBuses);
+ DPRINT1("MaximumNumberOfTargets: %lu\n",
DeviceExtension->Miniport.PortConfig.MaximumNumberOfTargets);
+ DPRINT1("MaximumNumberOfLogicalUnits: %lu\n",
DeviceExtension->Miniport.PortConfig.MaximumNumberOfLogicalUnits);
+
+ /* Scan all buses */
+ for (Bus = 0; Bus < DeviceExtension->Miniport.PortConfig.NumberOfBuses; Bus++)
+ {
+ DPRINT1("Scanning bus %ld\n", Bus);
+
+ /* Scan all targets */
+ for (Target = 0; Target <
DeviceExtension->Miniport.PortConfig.MaximumNumberOfTargets; Target++)
+ {
+ DPRINT1(" Scanning target %ld:%ld\n", Bus, Target);
+
+ /* Scan all logical units */
+ for (Lun = 0; Lun <
DeviceExtension->Miniport.PortConfig.MaximumNumberOfLogicalUnits; Lun++)
+ {
+ DPRINT1(" Scanning logical unit %ld:%ld:%ld\n", Bus, Target,
Lun);
+
+ Status = SpiSendInquiry(DeviceExtension->Device, Bus, Target, Lun);
+ DPRINT1("SpiSendInquiry returned 0x%08lx\n", Status);
+ }
+ }
+ }
+
+ DPRINT1("Done!\n");
+
+ return STATUS_SUCCESS;
+}
+
+
static
NTSTATUS
PortFdoQueryBusRelations(
@@ -254,6 +537,8 @@ PortFdoQueryBusRelations(
DPRINT1("PortFdoQueryBusRelations(%p %p)\n",
DeviceExtension, Information);
+ Status = PortFdoScanBus(DeviceExtension);
+
*Information = 0;
return Status;
@@ -282,6 +567,35 @@ PortFdoFilterRequirements(
}
+NTSTATUS
+NTAPI
+PortFdoScsi(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_ PIRP Irp)
+{
+ PFDO_DEVICE_EXTENSION DeviceExtension;
+// PIO_STACK_LOCATION Stack;
+ ULONG_PTR Information = 0;
+ NTSTATUS Status = STATUS_NOT_SUPPORTED;
+
+ DPRINT1("PortFdoScsi(%p %p)\n",
+ DeviceObject, Irp);
+
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ ASSERT(DeviceExtension);
+ ASSERT(DeviceExtension->ExtensionType == FdoExtension);
+
+// Stack = IoGetCurrentIrpStackLocation(Irp);
+
+
+ Irp->IoStatus.Information = Information;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+}
+
+
NTSTATUS
NTAPI
PortFdoPnp(
diff --git a/drivers/storage/port/storport/miniport.c
b/drivers/storage/port/storport/miniport.c
index 815e609031..e1aedcbfa5 100644
--- a/drivers/storage/port/storport/miniport.c
+++ b/drivers/storage/port/storport/miniport.c
@@ -362,4 +362,21 @@ MiniportHwInterrupt(
return Result;
}
+
+BOOLEAN
+MiniportStartIo(
+ _In_ PMINIPORT Miniport,
+ _In_ PSCSI_REQUEST_BLOCK Srb)
+{
+ BOOLEAN Result;
+
+ DPRINT1("MiniportHwStartIo(%p %p)\n",
+ Miniport, Srb);
+
+ Result =
Miniport->InitData->HwStartIo(&Miniport->MiniportExtension->HwDeviceExtension,
Srb);
+ DPRINT1("HwStartIo() returned %u\n", Result);
+
+ return Result;
+}
+
/* EOF */
diff --git a/drivers/storage/port/storport/misc.c b/drivers/storage/port/storport/misc.c
index f74fd3516f..1c9c73ae66 100644
--- a/drivers/storage/port/storport/misc.c
+++ b/drivers/storage/port/storport/misc.c
@@ -370,17 +370,4 @@ AllocateAddressMapping(
return STATUS_SUCCESS;
}
-#if defined(_M_AMD64)
-/* KeQuerySystemTime is an inline function,
- so we cannot forward the export to ntoskrnl */
-STORPORT_API
-VOID
-NTAPI
-StorPortQuerySystemTime(
- _Out_ PLARGE_INTEGER CurrentTime)
-{
- KeQuerySystemTime(CurrentTime);
-}
-#endif /* defined(_M_AMD64) */
-
/* EOF */
diff --git a/drivers/storage/port/storport/pdo.c b/drivers/storage/port/storport/pdo.c
index fb7280ccc0..8df3151e34 100644
--- a/drivers/storage/port/storport/pdo.c
+++ b/drivers/storage/port/storport/pdo.c
@@ -15,6 +15,21 @@
/* FUNCTIONS ******************************************************************/
+NTSTATUS
+NTAPI
+PortPdoScsi(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_ PIRP Irp)
+{
+ DPRINT1("PortPdoScsi()\n");
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+
NTSTATUS
NTAPI
PortPdoPnp(
diff --git a/drivers/storage/port/storport/precomp.h
b/drivers/storage/port/storport/precomp.h
index 5bd16f338f..84925ef1bc 100644
--- a/drivers/storage/port/storport/precomp.h
+++ b/drivers/storage/port/storport/precomp.h
@@ -29,6 +29,8 @@
#define TAG_ACCRESS_RANGE 'RAtS'
#define TAG_RESOURCE_LIST 'LRtS'
#define TAG_ADDRESS_MAPPING 'MAtS'
+#define TAG_INQUIRY_DATA 'QItS'
+#define TAG_SENSE_DATA 'NStS'
typedef enum
{
@@ -119,6 +121,12 @@ typedef struct _PDO_DEVICE_EXTENSION
/* fdo.c */
+NTSTATUS
+NTAPI
+PortFdoScsi(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_ PIRP Irp);
+
NTSTATUS
NTAPI
PortFdoPnp(
@@ -146,6 +154,11 @@ BOOLEAN
MiniportHwInterrupt(
_In_ PMINIPORT Miniport);
+BOOLEAN
+MiniportStartIo(
+ _In_ PMINIPORT Miniport,
+ _In_ PSCSI_REQUEST_BLOCK Srb);
+
/* misc.c */
NTSTATUS
@@ -206,6 +219,12 @@ AllocateAddressMapping(
/* pdo.c */
+NTSTATUS
+NTAPI
+PortPdoScsi(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_ PIRP Irp);
+
NTSTATUS
NTAPI
PortPdoPnp(
diff --git a/drivers/storage/port/storport/storport.c
b/drivers/storage/port/storport/storport.c
index a9fd3d07f8..03ec563949 100644
--- a/drivers/storage/port/storport/storport.c
+++ b/drivers/storage/port/storport/storport.c
@@ -100,6 +100,69 @@ PortGetDriverInitData(
}
+static
+VOID
+PortAcquireSpinLock(
+ PFDO_DEVICE_EXTENSION DeviceExtension,
+ STOR_SPINLOCK SpinLock,
+ PVOID LockContext,
+ PSTOR_LOCK_HANDLE LockHandle)
+{
+ DPRINT1("PortAcquireSpinLock(%p %lu %p %p)\n",
+ DeviceExtension, SpinLock, LockContext, LockHandle);
+
+ LockHandle->Lock = SpinLock;
+
+ switch (SpinLock)
+ {
+ case DpcLock: /* 1, */
+ DPRINT1("DpcLock\n");
+ break;
+
+ case StartIoLock: /* 2 */
+ DPRINT1("StartIoLock\n");
+ break;
+
+ case InterruptLock: /* 3 */
+ DPRINT1("InterruptLock\n");
+ if (DeviceExtension->Interrupt == NULL)
+ LockHandle->Context.OldIrql = 0;
+ else
+ LockHandle->Context.OldIrql =
KeAcquireInterruptSpinLock(DeviceExtension->Interrupt);
+ break;
+ }
+}
+
+
+static
+VOID
+PortReleaseSpinLock(
+ PFDO_DEVICE_EXTENSION DeviceExtension,
+ PSTOR_LOCK_HANDLE LockHandle)
+{
+ DPRINT1("PortReleaseSpinLock(%p %p)\n",
+ DeviceExtension, LockHandle);
+
+ switch (LockHandle->Lock)
+ {
+ case DpcLock: /* 1, */
+ DPRINT1("DpcLock\n");
+ break;
+
+ case StartIoLock: /* 2 */
+ DPRINT1("StartIoLock\n");
+ break;
+
+ case InterruptLock: /* 3 */
+ DPRINT1("InterruptLock\n");
+ if (DeviceExtension->Interrupt != NULL)
+ KeReleaseInterruptSpinLock(DeviceExtension->Interrupt,
+ LockHandle->Context.OldIrql);
+ break;
+ }
+}
+
+
static
NTSTATUS
NTAPI
@@ -280,13 +343,30 @@ PortDispatchScsi(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
+ PFDO_DEVICE_EXTENSION DeviceExtension;
+
DPRINT1("PortDispatchScsi(%p %p)\n",
DeviceObject, Irp);
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ DPRINT1("ExtensionType: %u\n", DeviceExtension->ExtensionType);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ switch (DeviceExtension->ExtensionType)
+ {
+ case FdoExtension:
+ return PortFdoScsi(DeviceObject,
+ Irp);
+
+ case PdoExtension:
+ return PortPdoScsi(DeviceObject,
+ Irp);
+
+ default:
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL;
+ }
return STATUS_SUCCESS;
}
@@ -742,10 +822,13 @@ StorPortGetPhysicalAddress(
// FIXME
- UNIMPLEMENTED;
- *Length = 0;
- PhysicalAddress.QuadPart = (LONGLONG)0;
+ PhysicalAddress = MmGetPhysicalAddress(VirtualAddress);
+ *Length = 1;
+// UNIMPLEMENTED;
+
+// *Length = 0;
+// PhysicalAddress.QuadPart = (LONGLONG)0;
return PhysicalAddress;
}
@@ -1012,11 +1095,16 @@ StorPortNotification(
PMINIPORT_DEVICE_EXTENSION MiniportExtension = NULL;
PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
PHW_PASSIVE_INITIALIZE_ROUTINE HwPassiveInitRoutine;
+ PSTORPORT_EXTENDED_FUNCTIONS *ppExtendedFunctions;
PBOOLEAN Result;
PSTOR_DPC Dpc;
PHW_DPC_ROUTINE HwDpcRoutine;
va_list ap;
+ STOR_SPINLOCK SpinLock;
+ PVOID LockContext;
+ PSTOR_LOCK_HANDLE LockHandle;
+
DPRINT1("StorPortNotification(%x %p)\n",
NotificationType, HwDeviceExtension);
@@ -1036,6 +1124,13 @@ StorPortNotification(
switch (NotificationType)
{
+ case GetExtendedFunctionTable:
+ DPRINT1("GetExtendedFunctionTable\n");
+ ppExtendedFunctions = (PSTORPORT_EXTENDED_FUNCTIONS*)va_arg(ap,
PSTORPORT_EXTENDED_FUNCTIONS*);
+ if (ppExtendedFunctions != NULL)
+ *ppExtendedFunctions = NULL; /* FIXME */
+ break;
+
case EnablePassiveInitialization:
DPRINT1("EnablePassiveInitialization\n");
HwPassiveInitRoutine = (PHW_PASSIVE_INITIALIZE_ROUTINE)va_arg(ap,
PHW_PASSIVE_INITIALIZE_ROUTINE);
@@ -1065,6 +1160,28 @@ StorPortNotification(
KeInitializeSpinLock(&Dpc->Lock);
break;
+ case AcquireSpinLock:
+ DPRINT1("AcquireSpinLock\n");
+ SpinLock = (STOR_SPINLOCK)va_arg(ap, STOR_SPINLOCK);
+ DPRINT1("SpinLock %lu\n", SpinLock);
+ LockContext = (PVOID)va_arg(ap, PVOID);
+ DPRINT1("LockContext %p\n", LockContext);
+ LockHandle = (PSTOR_LOCK_HANDLE)va_arg(ap, PSTOR_LOCK_HANDLE);
+ DPRINT1("LockHandle %p\n", LockHandle);
+ PortAcquireSpinLock(DeviceExtension,
+ SpinLock,
+ LockContext,
+ LockHandle);
+ break;
+
+ case ReleaseSpinLock:
+ DPRINT1("ReleaseSpinLock\n");
+ LockHandle = (PSTOR_LOCK_HANDLE)va_arg(ap, PSTOR_LOCK_HANDLE);
+ DPRINT1("LockHandle %p\n", LockHandle);
+ PortReleaseSpinLock(DeviceExtension,
+ LockHandle);
+ break;
+
default:
DPRINT1("Unsupported Notification %lx\n", NotificationType);
break;
@@ -1109,6 +1226,25 @@ StorPortPauseDevice(
}
+#if defined(_M_AMD64)
+/*
+ * @implemented
+ */
+/* KeQuerySystemTime is an inline function,
+ so we cannot forward the export to ntoskrnl */
+STORPORT_API
+VOID
+NTAPI
+StorPortQuerySystemTime(
+ _Out_ PLARGE_INTEGER CurrentTime)
+{
+ DPRINT1("StorPortQuerySystemTime(%p)\n", CurrentTime);
+
+ KeQuerySystemTime(CurrentTime);
+}
+#endif /* defined(_M_AMD64) */
+
+
/*
* @unimplemented
*/
diff --git a/drivers/storage/port/storport/storport.spec
b/drivers/storage/port/storport/storport.spec
index 310e201f9e..a36e5ed49a 100644
--- a/drivers/storage/port/storport/storport.spec
+++ b/drivers/storage/port/storport/storport.spec
@@ -24,10 +24,10 @@
@ stdcall StorPortLogError(ptr ptr long long long long long)
@ stdcall StorPortMoveMemory(ptr ptr long)
@ cdecl StorPortNotification()
-@ stdcall -arch=i386 StorPortQuerySystemTime(ptr) NTOSKRNL.KeQuerySystemTime
-@ stdcall -arch=amd64 StorPortQuerySystemTime(ptr)
@ stdcall StorPortPause(ptr long)
@ stdcall StorPortPauseDevice(ptr long long long long)
+@ stdcall -arch=i386 StorPortQuerySystemTime(ptr) NTOSKRNL.KeQuerySystemTime
+@ stdcall -arch=amd64 StorPortQuerySystemTime(ptr)
@ stdcall StorPortReadPortBufferUchar(ptr ptr ptr long)
@ stdcall StorPortReadPortBufferUlong(ptr ptr ptr long)
@ stdcall StorPortReadPortBufferUshort(ptr ptr ptr long)
diff --git a/sdk/include/ddk/storport.h b/sdk/include/ddk/storport.h
index 64a6e1059d..44d5d96d27 100644
--- a/sdk/include/ddk/storport.h
+++ b/sdk/include/ddk/storport.h
@@ -57,7 +57,14 @@ extern "C" {
#define CDB10GENERIC_LENGTH 10
#define CDB12GENERIC_LENGTH 12
-#define INQUIRYDATABUFFERSIZE 36
+#define INQUIRYDATABUFFERSIZE 36
+#define SENSE_BUFFER_SIZE 18
+#define MAX_SENSE_BUFFER_SIZE 255
+
+#define FILE_DEVICE_SCSI 0x0000001b
+#define IOCTL_SCSI_EXECUTE_IN ((FILE_DEVICE_SCSI << 16) + 0x0011)
+#define IOCTL_SCSI_EXECUTE_OUT ((FILE_DEVICE_SCSI << 16) + 0x0012)
+#define IOCTL_SCSI_EXECUTE_NONE ((FILE_DEVICE_SCSI << 16) + 0x0013)
#define MODE_PAGE_VENDOR_SPECIFIC 0x00
#define MODE_PAGE_ERROR_RECOVERY 0x01
@@ -563,6 +570,12 @@ typedef enum _STOR_EVENT_ASSOCIATION_ENUM
StorEventInvalidAssociation
} STOR_EVENT_ASSOCIATION_ENUM;
+typedef enum _GETSGSTATUS
+{
+ SG_ALLOCATED = 0,
+ SG_BUFFER_TOO_SMALL
+} GETSGSTATUS, *PGETSGSTATUS;
+
typedef struct _SCSI_REQUEST_BLOCK
{
USHORT Length;
@@ -2182,6 +2195,64 @@ VOID
_In_ PSTOR_SCATTER_GATHER_LIST ScatterGather,
_In_ PVOID Context);
+typedef
+BOOLEAN
+(NTAPI *PStorPortGetMessageInterruptInformation)(
+ _In_ PVOID HwDeviceExtension,
+ _In_ ULONG MessageId,
+ _Out_ PMESSAGE_INTERRUPT_INFORMATION InterruptInfo);
+
+typedef
+VOID
+(NTAPI *PStorPortPutScatterGatherList)(
+ _In_ PVOID HwDeviceExtension,
+ _In_ PSTOR_SCATTER_GATHER_LIST ScatterGatherList,
+ _In_ BOOLEAN WriteToDevice);
+
+typedef
+GETSGSTATUS
+(NTAPI *PStorPortBuildScatterGatherList)(
+ _In_ PVOID HwDeviceExtension,
+ _In_ PVOID Mdl,
+ _In_ PVOID CurrentVa,
+ _In_ ULONG Length,
+ _In_ PpostScaterGatherExecute ExecutionRoutine,
+ _In_ PVOID Context,
+ _In_ BOOLEAN WriteToDevice,
+ _Inout_ PVOID ScatterGatherBuffer,
+ _In_ ULONG ScatterGatherBufferLength);
+
+typedef
+VOID
+(NTAPI *PStorPortFreePool)(
+ _In_ PVOID PMemory,
+ _In_ PVOID HwDeviceExtension,
+ _In_opt_ PVOID PMdl);
+
+typedef
+PVOID
+(NTAPI *PStorPortAllocatePool)(
+ _In_ ULONG NumberOfBytes,
+ _In_ ULONG Tag,
+ _In_ PVOID HwDeviceExtension,
+ _Out_ PVOID *PMdl);
+
+typedef
+PVOID
+(NTAPI *PStorPortGetSystemAddress)(
+ _In_ PSCSI_REQUEST_BLOCK Srb);
+
+typedef struct _STORPORT_EXTENDED_FUNCTIONS
+{
+ ULONG Version;
+ PStorPortGetMessageInterruptInformation GetMessageInterruptInformation;
+ PStorPortPutScatterGatherList PutScatterGatherList;
+ PStorPortBuildScatterGatherList BuildScatterGatherList;
+ PStorPortFreePool FreePool;
+ PStorPortAllocatePool AllocatePool;
+ PStorPortGetSystemAddress GetSystemAddress;
+} STORPORT_EXTENDED_FUNCTIONS, *PSTORPORT_EXTENDED_FUNCTIONS;
+
typedef struct _HW_INITIALIZATION_DATA
{
ULONG HwInitializationDataSize;