mirror of
https://github.com/reactos/reactos.git
synced 2024-10-04 08:25:53 +00:00
[STORPORT] Detect attached devices
This commit is contained in:
parent
fd4752450f
commit
be88574f59
|
@ -244,29 +244,26 @@ PortFdoStartDevice(
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
SpiSendInquiry(IN PDEVICE_OBJECT DeviceObject,
|
PortSendInquiry(
|
||||||
ULONG Bus, ULONG Target, ULONG Lun)
|
_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_ ULONG Bus,
|
||||||
|
_In_ ULONG Target,
|
||||||
|
_In_ ULONG Lun)
|
||||||
{
|
{
|
||||||
// IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
// PIO_STACK_LOCATION IrpStack;
|
|
||||||
// KEVENT Event;
|
|
||||||
// KIRQL Irql;
|
|
||||||
// PIRP Irp;
|
|
||||||
NTSTATUS Status;
|
|
||||||
PINQUIRYDATA InquiryBuffer;
|
PINQUIRYDATA InquiryBuffer;
|
||||||
PUCHAR /*PSENSE_DATA*/ SenseBuffer;
|
PUCHAR /*PSENSE_DATA*/ SenseBuffer;
|
||||||
// BOOLEAN KeepTrying = TRUE;
|
BOOLEAN KeepTrying = TRUE;
|
||||||
// ULONG RetryCount = 0;
|
ULONG RetryCount = 0;
|
||||||
SCSI_REQUEST_BLOCK Srb;
|
SCSI_REQUEST_BLOCK Srb;
|
||||||
PCDB Cdb;
|
PCDB Cdb;
|
||||||
// PSCSI_PORT_LUN_EXTENSION LunExtension;
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
// PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
|
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
PVOID SrbExtension = NULL;
|
PVOID SrbExtension = NULL;
|
||||||
BOOLEAN ret;
|
BOOLEAN ret;
|
||||||
|
PUNIT_DATA UnitData;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT1("SpiSendInquiry() called\n");
|
DPRINT("PortSendInquiry(%p %lu %lu %lu)\n",
|
||||||
|
DeviceObject, Bus, Target, Lun);
|
||||||
|
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
@ -283,7 +280,9 @@ PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
if (DeviceExtension->Miniport.PortConfig.SrbExtensionSize != 0)
|
if (DeviceExtension->Miniport.PortConfig.SrbExtensionSize != 0)
|
||||||
{
|
{
|
||||||
SrbExtension = ExAllocatePoolWithTag(NonPagedPool, DeviceExtension->Miniport.PortConfig.SrbExtensionSize, TAG_SENSE_DATA);
|
SrbExtension = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
DeviceExtension->Miniport.PortConfig.SrbExtensionSize,
|
||||||
|
TAG_SENSE_DATA);
|
||||||
if (SrbExtension == NULL)
|
if (SrbExtension == NULL)
|
||||||
{
|
{
|
||||||
ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA);
|
ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA);
|
||||||
|
@ -292,33 +291,8 @@ PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// while (KeepTrying)
|
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 */
|
/* Prepare SRB */
|
||||||
RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
|
RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
|
||||||
|
|
||||||
|
@ -340,108 +314,55 @@ PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
Srb.SrbExtension = SrbExtension;
|
Srb.SrbExtension = SrbExtension;
|
||||||
|
|
||||||
/* Attach Srb to the Irp */
|
|
||||||
// IrpStack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
// IrpStack->Parameters.Scsi.Srb = &Srb;
|
|
||||||
|
|
||||||
/* Fill in CDB */
|
/* Fill in CDB */
|
||||||
Cdb = (PCDB)Srb.Cdb;
|
Cdb = (PCDB)Srb.Cdb;
|
||||||
Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
|
Cdb->CDB6INQUIRY3.OperationCode = SCSIOP_INQUIRY;
|
||||||
Cdb->CDB6INQUIRY.LogicalUnitNumber = Lun;
|
Cdb->CDB6INQUIRY3.EnableVitalProductData = 1;
|
||||||
Cdb->CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE;
|
Cdb->CDB6INQUIRY3.CommandSupportData = 0;
|
||||||
|
Cdb->CDB6INQUIRY3.PageCode = 0; //??
|
||||||
/* Call the driver */
|
Cdb->CDB6INQUIRY3.AllocationLength = INQUIRYDATABUFFERSIZE;
|
||||||
|
Cdb->CDB6INQUIRY3.Control = 0;
|
||||||
|
|
||||||
|
/* Call the miniport driver */
|
||||||
ret = MiniportStartIo(&DeviceExtension->Miniport,
|
ret = MiniportStartIo(&DeviceExtension->Miniport,
|
||||||
&Srb);
|
&Srb);
|
||||||
DPRINT1("MiniportStartIo returned %u\n", ret);
|
if (ret == FALSE)
|
||||||
|
{
|
||||||
// Status = IoCallDriver(DeviceObject, Irp);
|
Status = STATUS_IO_DEVICE_ERROR;
|
||||||
|
KeepTrying = FALSE;
|
||||||
/* Wait for it to complete */
|
continue;
|
||||||
// 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);
|
|
||||||
|
|
||||||
|
DPRINT("SrbStatus 0x%08lx\n", Srb.SrbStatus);
|
||||||
if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_SUCCESS)
|
if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
DPRINT("Found a device!\n");
|
||||||
|
|
||||||
|
UnitData = ExAllocatePool(NonPagedPool, sizeof(UNIT_DATA));
|
||||||
|
if (UnitData == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
KeepTrying = FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* All fine, copy data over */
|
/* All fine, copy data over */
|
||||||
// RtlCopyMemory(LunInfo->InquiryData,
|
RtlCopyMemory(&UnitData->InquiryData,
|
||||||
// InquiryBuffer,
|
Srb.DataBuffer,
|
||||||
// INQUIRYDATABUFFERSIZE);
|
Srb.DataTransferLength);
|
||||||
|
|
||||||
|
InsertTailList(&DeviceExtension->UnitListHead,
|
||||||
|
&UnitData->ListEntry);
|
||||||
|
DeviceExtension->UnitCount++;
|
||||||
|
|
||||||
/* Quit the loop */
|
/* Quit the loop */
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
// KeepTrying = FALSE;
|
KeepTrying = FALSE;
|
||||||
// continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Inquiry SRB failed with SrbStatus 0x%08X\n", Srb.SrbStatus);
|
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 */
|
/* Retry a couple of times if no timeout happened */
|
||||||
if ((RetryCount < 2) &&
|
if ((RetryCount < 2) &&
|
||||||
(SRB_STATUS(Srb.SrbStatus) != SRB_STATUS_NO_DEVICE) &&
|
(SRB_STATUS(Srb.SrbStatus) != SRB_STATUS_NO_DEVICE) &&
|
||||||
|
@ -467,8 +388,6 @@ DPRINT1("MiniportStartIo returned %u\n", ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free buffers */
|
/* Free buffers */
|
||||||
if (SrbExtension != NULL)
|
if (SrbExtension != NULL)
|
||||||
|
@ -477,7 +396,7 @@ DPRINT1("MiniportStartIo returned %u\n", ret);
|
||||||
ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA);
|
ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA);
|
||||||
ExFreePoolWithTag(InquiryBuffer, TAG_INQUIRY_DATA);
|
ExFreePoolWithTag(InquiryBuffer, TAG_INQUIRY_DATA);
|
||||||
|
|
||||||
DPRINT("SpiSendInquiry() done with Status 0x%08X\n", Status);
|
DPRINT("PortSendInquiry() returns 0x%08lx\n", Status);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -491,7 +410,6 @@ PortFdoScanBus(
|
||||||
ULONG Bus, Target, Lun;
|
ULONG Bus, Target, Lun;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
|
||||||
DPRINT1("PortFdoScanBus(%p)\n",
|
DPRINT1("PortFdoScanBus(%p)\n",
|
||||||
DeviceExtension);
|
DeviceExtension);
|
||||||
|
|
||||||
|
@ -514,13 +432,15 @@ PortFdoScanBus(
|
||||||
{
|
{
|
||||||
DPRINT1(" Scanning logical unit %ld:%ld:%ld\n", Bus, Target, Lun);
|
DPRINT1(" Scanning logical unit %ld:%ld:%ld\n", Bus, Target, Lun);
|
||||||
|
|
||||||
Status = SpiSendInquiry(DeviceExtension->Device, Bus, Target, Lun);
|
Status = PortSendInquiry(DeviceExtension->Device, Bus, Target, Lun);
|
||||||
DPRINT1("SpiSendInquiry returned 0x%08lx\n", Status);
|
DPRINT1("PortSendInquiry returned 0x%08lx\n", Status);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("Done!\n");
|
DPRINT("Done!\n");
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -539,6 +459,8 @@ PortFdoQueryBusRelations(
|
||||||
|
|
||||||
Status = PortFdoScanBus(DeviceExtension);
|
Status = PortFdoScanBus(DeviceExtension);
|
||||||
|
|
||||||
|
DPRINT1("Units found: %lu\n", DeviceExtension->UnitCount);
|
||||||
|
|
||||||
*Information = 0;
|
*Information = 0;
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -81,6 +81,12 @@ typedef struct _MINIPORT
|
||||||
PMINIPORT_DEVICE_EXTENSION MiniportExtension;
|
PMINIPORT_DEVICE_EXTENSION MiniportExtension;
|
||||||
} MINIPORT, *PMINIPORT;
|
} MINIPORT, *PMINIPORT;
|
||||||
|
|
||||||
|
typedef struct _UNIT_DATA
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
INQUIRYDATA InquiryData;
|
||||||
|
} UNIT_DATA, *PUNIT_DATA;
|
||||||
|
|
||||||
typedef struct _FDO_DEVICE_EXTENSION
|
typedef struct _FDO_DEVICE_EXTENSION
|
||||||
{
|
{
|
||||||
EXTENSION_TYPE ExtensionType;
|
EXTENSION_TYPE ExtensionType;
|
||||||
|
@ -105,6 +111,9 @@ typedef struct _FDO_DEVICE_EXTENSION
|
||||||
PHW_PASSIVE_INITIALIZE_ROUTINE HwPassiveInitRoutine;
|
PHW_PASSIVE_INITIALIZE_ROUTINE HwPassiveInitRoutine;
|
||||||
PKINTERRUPT Interrupt;
|
PKINTERRUPT Interrupt;
|
||||||
ULONG InterruptIrql;
|
ULONG InterruptIrql;
|
||||||
|
|
||||||
|
ULONG UnitCount;
|
||||||
|
LIST_ENTRY UnitListHead;
|
||||||
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,8 @@ PortAddDevice(
|
||||||
|
|
||||||
DeviceExtension->PnpState = dsStopped;
|
DeviceExtension->PnpState = dsStopped;
|
||||||
|
|
||||||
|
InitializeListHead(&DeviceExtension->UnitListHead);
|
||||||
|
|
||||||
/* Attach the FDO to the device stack */
|
/* Attach the FDO to the device stack */
|
||||||
Status = IoAttachDeviceToDeviceStackSafe(Fdo,
|
Status = IoAttachDeviceToDeviceStackSafe(Fdo,
|
||||||
PhysicalDeviceObject,
|
PhysicalDeviceObject,
|
||||||
|
@ -1104,6 +1106,7 @@ StorPortNotification(
|
||||||
STOR_SPINLOCK SpinLock;
|
STOR_SPINLOCK SpinLock;
|
||||||
PVOID LockContext;
|
PVOID LockContext;
|
||||||
PSTOR_LOCK_HANDLE LockHandle;
|
PSTOR_LOCK_HANDLE LockHandle;
|
||||||
|
PSCSI_REQUEST_BLOCK Srb;
|
||||||
|
|
||||||
DPRINT1("StorPortNotification(%x %p)\n",
|
DPRINT1("StorPortNotification(%x %p)\n",
|
||||||
NotificationType, HwDeviceExtension);
|
NotificationType, HwDeviceExtension);
|
||||||
|
@ -1124,6 +1127,17 @@ StorPortNotification(
|
||||||
|
|
||||||
switch (NotificationType)
|
switch (NotificationType)
|
||||||
{
|
{
|
||||||
|
case RequestComplete:
|
||||||
|
DPRINT1("RequestComplete\n");
|
||||||
|
Srb = (PSCSI_REQUEST_BLOCK)va_arg(ap, PSCSI_REQUEST_BLOCK);
|
||||||
|
DPRINT1("Srb %p\n", Srb);
|
||||||
|
if (Srb->OriginalRequest != NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("Need to complete the IRP!\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case GetExtendedFunctionTable:
|
case GetExtendedFunctionTable:
|
||||||
DPRINT1("GetExtendedFunctionTable\n");
|
DPRINT1("GetExtendedFunctionTable\n");
|
||||||
ppExtendedFunctions = (PSTORPORT_EXTENDED_FUNCTIONS*)va_arg(ap, PSTORPORT_EXTENDED_FUNCTIONS*);
|
ppExtendedFunctions = (PSTORPORT_EXTENDED_FUNCTIONS*)va_arg(ap, PSTORPORT_EXTENDED_FUNCTIONS*);
|
||||||
|
|
Loading…
Reference in a new issue