mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +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
|
@ -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
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
PortFdoQueryBusRelations(
|
PortFdoQueryBusRelations(
|
||||||
|
@ -254,6 +537,8 @@ PortFdoQueryBusRelations(
|
||||||
DPRINT1("PortFdoQueryBusRelations(%p %p)\n",
|
DPRINT1("PortFdoQueryBusRelations(%p %p)\n",
|
||||||
DeviceExtension, Information);
|
DeviceExtension, Information);
|
||||||
|
|
||||||
|
Status = PortFdoScanBus(DeviceExtension);
|
||||||
|
|
||||||
*Information = 0;
|
*Information = 0;
|
||||||
|
|
||||||
return Status;
|
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PortFdoPnp(
|
PortFdoPnp(
|
||||||
|
|
|
@ -362,4 +362,21 @@ MiniportHwInterrupt(
|
||||||
return Result;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -370,17 +370,4 @@ AllocateAddressMapping(
|
||||||
return STATUS_SUCCESS;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -15,6 +15,21 @@
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* 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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PortPdoPnp(
|
PortPdoPnp(
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#define TAG_ACCRESS_RANGE 'RAtS'
|
#define TAG_ACCRESS_RANGE 'RAtS'
|
||||||
#define TAG_RESOURCE_LIST 'LRtS'
|
#define TAG_RESOURCE_LIST 'LRtS'
|
||||||
#define TAG_ADDRESS_MAPPING 'MAtS'
|
#define TAG_ADDRESS_MAPPING 'MAtS'
|
||||||
|
#define TAG_INQUIRY_DATA 'QItS'
|
||||||
|
#define TAG_SENSE_DATA 'NStS'
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -119,6 +121,12 @@ typedef struct _PDO_DEVICE_EXTENSION
|
||||||
|
|
||||||
/* fdo.c */
|
/* fdo.c */
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PortFdoScsi(
|
||||||
|
_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_ PIRP Irp);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PortFdoPnp(
|
PortFdoPnp(
|
||||||
|
@ -146,6 +154,11 @@ BOOLEAN
|
||||||
MiniportHwInterrupt(
|
MiniportHwInterrupt(
|
||||||
_In_ PMINIPORT Miniport);
|
_In_ PMINIPORT Miniport);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MiniportStartIo(
|
||||||
|
_In_ PMINIPORT Miniport,
|
||||||
|
_In_ PSCSI_REQUEST_BLOCK Srb);
|
||||||
|
|
||||||
/* misc.c */
|
/* misc.c */
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -206,6 +219,12 @@ AllocateAddressMapping(
|
||||||
|
|
||||||
/* pdo.c */
|
/* pdo.c */
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PortPdoScsi(
|
||||||
|
_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_ PIRP Irp);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PortPdoPnp(
|
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
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -280,13 +343,30 @@ PortDispatchScsi(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
DPRINT1("PortDispatchScsi(%p %p)\n",
|
DPRINT1("PortDispatchScsi(%p %p)\n",
|
||||||
DeviceObject, Irp);
|
DeviceObject, Irp);
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
Irp->IoStatus.Information = 0;
|
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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -742,10 +822,13 @@ StorPortGetPhysicalAddress(
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
|
|
||||||
*Length = 0;
|
PhysicalAddress = MmGetPhysicalAddress(VirtualAddress);
|
||||||
PhysicalAddress.QuadPart = (LONGLONG)0;
|
*Length = 1;
|
||||||
|
// UNIMPLEMENTED;
|
||||||
|
|
||||||
|
// *Length = 0;
|
||||||
|
// PhysicalAddress.QuadPart = (LONGLONG)0;
|
||||||
|
|
||||||
return PhysicalAddress;
|
return PhysicalAddress;
|
||||||
}
|
}
|
||||||
|
@ -1012,11 +1095,16 @@ StorPortNotification(
|
||||||
PMINIPORT_DEVICE_EXTENSION MiniportExtension = NULL;
|
PMINIPORT_DEVICE_EXTENSION MiniportExtension = NULL;
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
|
PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
|
||||||
PHW_PASSIVE_INITIALIZE_ROUTINE HwPassiveInitRoutine;
|
PHW_PASSIVE_INITIALIZE_ROUTINE HwPassiveInitRoutine;
|
||||||
|
PSTORPORT_EXTENDED_FUNCTIONS *ppExtendedFunctions;
|
||||||
PBOOLEAN Result;
|
PBOOLEAN Result;
|
||||||
PSTOR_DPC Dpc;
|
PSTOR_DPC Dpc;
|
||||||
PHW_DPC_ROUTINE HwDpcRoutine;
|
PHW_DPC_ROUTINE HwDpcRoutine;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
STOR_SPINLOCK SpinLock;
|
||||||
|
PVOID LockContext;
|
||||||
|
PSTOR_LOCK_HANDLE LockHandle;
|
||||||
|
|
||||||
DPRINT1("StorPortNotification(%x %p)\n",
|
DPRINT1("StorPortNotification(%x %p)\n",
|
||||||
NotificationType, HwDeviceExtension);
|
NotificationType, HwDeviceExtension);
|
||||||
|
|
||||||
|
@ -1036,6 +1124,13 @@ StorPortNotification(
|
||||||
|
|
||||||
switch (NotificationType)
|
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:
|
case EnablePassiveInitialization:
|
||||||
DPRINT1("EnablePassiveInitialization\n");
|
DPRINT1("EnablePassiveInitialization\n");
|
||||||
HwPassiveInitRoutine = (PHW_PASSIVE_INITIALIZE_ROUTINE)va_arg(ap, PHW_PASSIVE_INITIALIZE_ROUTINE);
|
HwPassiveInitRoutine = (PHW_PASSIVE_INITIALIZE_ROUTINE)va_arg(ap, PHW_PASSIVE_INITIALIZE_ROUTINE);
|
||||||
|
@ -1065,6 +1160,28 @@ StorPortNotification(
|
||||||
KeInitializeSpinLock(&Dpc->Lock);
|
KeInitializeSpinLock(&Dpc->Lock);
|
||||||
break;
|
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:
|
default:
|
||||||
DPRINT1("Unsupported Notification %lx\n", NotificationType);
|
DPRINT1("Unsupported Notification %lx\n", NotificationType);
|
||||||
break;
|
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
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
@ stdcall StorPortLogError(ptr ptr long long long long long)
|
@ stdcall StorPortLogError(ptr ptr long long long long long)
|
||||||
@ stdcall StorPortMoveMemory(ptr ptr long)
|
@ stdcall StorPortMoveMemory(ptr ptr long)
|
||||||
@ cdecl StorPortNotification()
|
@ cdecl StorPortNotification()
|
||||||
@ stdcall -arch=i386 StorPortQuerySystemTime(ptr) NTOSKRNL.KeQuerySystemTime
|
|
||||||
@ stdcall -arch=amd64 StorPortQuerySystemTime(ptr)
|
|
||||||
@ stdcall StorPortPause(ptr long)
|
@ stdcall StorPortPause(ptr long)
|
||||||
@ stdcall StorPortPauseDevice(ptr long long long 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 StorPortReadPortBufferUchar(ptr ptr ptr long)
|
||||||
@ stdcall StorPortReadPortBufferUlong(ptr ptr ptr long)
|
@ stdcall StorPortReadPortBufferUlong(ptr ptr ptr long)
|
||||||
@ stdcall StorPortReadPortBufferUshort(ptr ptr ptr long)
|
@ stdcall StorPortReadPortBufferUshort(ptr ptr ptr long)
|
||||||
|
|
|
@ -57,7 +57,14 @@ extern "C" {
|
||||||
#define CDB10GENERIC_LENGTH 10
|
#define CDB10GENERIC_LENGTH 10
|
||||||
#define CDB12GENERIC_LENGTH 12
|
#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_VENDOR_SPECIFIC 0x00
|
||||||
#define MODE_PAGE_ERROR_RECOVERY 0x01
|
#define MODE_PAGE_ERROR_RECOVERY 0x01
|
||||||
|
@ -563,6 +570,12 @@ typedef enum _STOR_EVENT_ASSOCIATION_ENUM
|
||||||
StorEventInvalidAssociation
|
StorEventInvalidAssociation
|
||||||
} STOR_EVENT_ASSOCIATION_ENUM;
|
} STOR_EVENT_ASSOCIATION_ENUM;
|
||||||
|
|
||||||
|
typedef enum _GETSGSTATUS
|
||||||
|
{
|
||||||
|
SG_ALLOCATED = 0,
|
||||||
|
SG_BUFFER_TOO_SMALL
|
||||||
|
} GETSGSTATUS, *PGETSGSTATUS;
|
||||||
|
|
||||||
typedef struct _SCSI_REQUEST_BLOCK
|
typedef struct _SCSI_REQUEST_BLOCK
|
||||||
{
|
{
|
||||||
USHORT Length;
|
USHORT Length;
|
||||||
|
@ -2182,6 +2195,64 @@ VOID
|
||||||
_In_ PSTOR_SCATTER_GATHER_LIST ScatterGather,
|
_In_ PSTOR_SCATTER_GATHER_LIST ScatterGather,
|
||||||
_In_ PVOID Context);
|
_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
|
typedef struct _HW_INITIALIZATION_DATA
|
||||||
{
|
{
|
||||||
ULONG HwInitializationDataSize;
|
ULONG HwInitializationDataSize;
|
||||||
|
|
Loading…
Reference in a new issue