[STORPORT] Detect attached devices
authorEric Kohl <eric.kohl@reactos.org>
Sun, 2 Jun 2019 21:30:02 +0000 (23:30 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 2 Jun 2019 21:30:02 +0000 (23:30 +0200)
drivers/storage/port/storport/fdo.c
drivers/storage/port/storport/precomp.h
drivers/storage/port/storport/storport.c

index e20fd68..a2be47c 100644 (file)
@@ -244,29 +244,26 @@ PortFdoStartDevice(
 
 
 static NTSTATUS
-SpiSendInquiry(IN PDEVICE_OBJECT DeviceObject,
-               ULONG Bus, ULONG Target, ULONG Lun)
+PortSendInquiry(
+    _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;
     PUCHAR /*PSENSE_DATA*/ SenseBuffer;
-//    BOOLEAN KeepTrying = TRUE;
-//    ULONG RetryCount = 0;
+    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;
+    PFDO_DEVICE_EXTENSION DeviceExtension;
     PVOID SrbExtension = NULL;
     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;
 
@@ -283,7 +280,9 @@ PFDO_DEVICE_EXTENSION DeviceExtension;
 
     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)
         {
             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 */
         RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
 
@@ -340,134 +314,79 @@ PFDO_DEVICE_EXTENSION DeviceExtension;
 
         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 */
-
-
+        Cdb->CDB6INQUIRY3.OperationCode = SCSIOP_INQUIRY;
+        Cdb->CDB6INQUIRY3.EnableVitalProductData = 1;
+        Cdb->CDB6INQUIRY3.CommandSupportData = 0;
+        Cdb->CDB6INQUIRY3.PageCode = 0; //??
+        Cdb->CDB6INQUIRY3.AllocationLength = INQUIRYDATABUFFERSIZE;
+        Cdb->CDB6INQUIRY3.Control = 0;
+
+        /* Call the miniport 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)
+        if (ret == FALSE)
         {
-            /* All fine, copy data over */
-//            RtlCopyMemory(LunInfo->InquiryData,
-//                          InquiryBuffer,
-//                          INQUIRYDATABUFFERSIZE);
-
-            /* Quit the loop */
-            Status = STATUS_SUCCESS;
-//            KeepTrying = FALSE;
-//            continue;
+            Status = STATUS_IO_DEVICE_ERROR;
+            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)
+        DPRINT("SrbStatus 0x%08lx\n", Srb.SrbStatus);
+        if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_SUCCESS)
         {
-            /* Something weird happened, deal with it (unfreeze the queue) */
-            KeepTrying = FALSE;
+            DPRINT("Found a device!\n");
 
-            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);
-        }
+            UnitData = ExAllocatePool(NonPagedPool, sizeof(UNIT_DATA));
+            if (UnitData == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                KeepTrying = FALSE;
+                continue;
+            }
 
-        /* Check if data overrun happened */
-        if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN)
-        {
-            DPRINT("Data overrun at TargetId %d\n", LunInfo->TargetId);
+            /* All fine, copy data over */
+            RtlCopyMemory(&UnitData->InquiryData,
+                          Srb.DataBuffer,
+                          Srb.DataTransferLength);
 
-            /* Nothing dramatic, just copy data, but limiting the size */
-            RtlCopyMemory(LunInfo->InquiryData,
-                            InquiryBuffer,
-                            (Srb.DataTransferLength > INQUIRYDATABUFFERSIZE) ?
-                            INQUIRYDATABUFFERSIZE : Srb.DataTransferLength);
+            InsertTailList(&DeviceExtension->UnitListHead,
+                           &UnitData->ListEntry);
+            DeviceExtension->UnitCount++;
 
             /* Quit the loop */
             Status = STATUS_SUCCESS;
             KeepTrying = FALSE;
+            continue;
         }
-        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;
+        DPRINT("Inquiry SRB failed with SrbStatus 0x%08X\n", Srb.SrbStatus);
+
+        /* 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
         {
-            /* 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))
+            /* 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)
             {
-                RetryCount++;
-                KeepTrying = TRUE;
+                Status = STATUS_INVALID_DEVICE_REQUEST;
             }
             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;
-                }
+                Status = STATUS_IO_DEVICE_ERROR;
             }
         }
-#endif
     }
 
     /* Free buffers */
@@ -477,7 +396,7 @@ DPRINT1("MiniportStartIo returned %u\n", ret);
     ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA);
     ExFreePoolWithTag(InquiryBuffer, TAG_INQUIRY_DATA);
 
-    DPRINT("SpiSendInquiry() done with Status 0x%08X\n", Status);
+    DPRINT("PortSendInquiry() returns 0x%08lx\n", Status);
 
     return Status;
 }
@@ -491,7 +410,6 @@ PortFdoScanBus(
     ULONG Bus, Target, Lun;
     NTSTATUS Status;
 
-
     DPRINT1("PortFdoScanBus(%p)\n",
             DeviceExtension);
 
@@ -514,13 +432,15 @@ PortFdoScanBus(
             {
                 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);
+                Status = PortSendInquiry(DeviceExtension->Device, Bus, Target, Lun);
+                DPRINT1("PortSendInquiry returned 0x%08lx\n", Status);
+                if (!NT_SUCCESS(Status))
+                    break;
             }
         }
     }
 
-    DPRINT1("Done!\n");
+    DPRINT("Done!\n");
 
     return STATUS_SUCCESS;
 }
@@ -539,6 +459,8 @@ PortFdoQueryBusRelations(
 
     Status = PortFdoScanBus(DeviceExtension);
 
+    DPRINT1("Units found: %lu\n", DeviceExtension->UnitCount);
+
     *Information = 0;
 
     return Status;
index 84925ef..046dd0b 100644 (file)
@@ -81,6 +81,12 @@ typedef struct _MINIPORT
     PMINIPORT_DEVICE_EXTENSION MiniportExtension;
 } MINIPORT, *PMINIPORT;
 
+typedef struct _UNIT_DATA
+{
+    LIST_ENTRY ListEntry;
+    INQUIRYDATA InquiryData;
+} UNIT_DATA, *PUNIT_DATA;
+
 typedef struct _FDO_DEVICE_EXTENSION
 {
     EXTENSION_TYPE ExtensionType;
@@ -105,6 +111,9 @@ typedef struct _FDO_DEVICE_EXTENSION
     PHW_PASSIVE_INITIALIZE_ROUTINE HwPassiveInitRoutine;
     PKINTERRUPT Interrupt;
     ULONG InterruptIrql;
+
+    ULONG UnitCount;
+    LIST_ENTRY UnitListHead;
 } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
 
 
index 03ec563..5bed391 100644 (file)
@@ -223,6 +223,8 @@ PortAddDevice(
 
     DeviceExtension->PnpState = dsStopped;
 
+    InitializeListHead(&DeviceExtension->UnitListHead);
+
     /* Attach the FDO to the device stack */
     Status = IoAttachDeviceToDeviceStackSafe(Fdo,
                                              PhysicalDeviceObject,
@@ -1104,6 +1106,7 @@ StorPortNotification(
     STOR_SPINLOCK SpinLock;
     PVOID LockContext;
     PSTOR_LOCK_HANDLE LockHandle;
+    PSCSI_REQUEST_BLOCK Srb;
 
     DPRINT1("StorPortNotification(%x %p)\n",
             NotificationType, HwDeviceExtension);
@@ -1124,6 +1127,17 @@ StorPortNotification(
 
     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:
             DPRINT1("GetExtendedFunctionTable\n");
             ppExtendedFunctions = (PSTORPORT_EXTENDED_FUNCTIONS*)va_arg(ap, PSTORPORT_EXTENDED_FUNCTIONS*);