mirror of
https://github.com/reactos/reactos.git
synced 2025-02-21 16:04:57 +00:00
[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.
This commit is contained in:
parent
8c726ae0d2
commit
f7c01906e7
8 changed files with 581 additions and 22 deletions
|
@ -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(
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue