]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
MdeModulePkg/ScsiBusDxe: remove redundant "else" after "break" statement
[mirror_edk2.git] / MdeModulePkg / Bus / Scsi / ScsiBusDxe / ScsiBus.c
index 7263403abbabb39f10fcfb8eab9963060a796306..1068770cd87f02903ca28e31b4ae94da09487fcc 100644 (file)
@@ -2,8 +2,8 @@
   SCSI Bus driver that layers on every SCSI Pass Thru and\r
   Extended SCSI Pass Thru protocol in the system.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
@@ -26,14 +26,6 @@ EFI_DRIVER_BINDING_PROTOCOL gSCSIBusDriverBinding = {
   NULL\r
 };\r
 \r
-\r
-//\r
-// The ScsiBusProtocol is just used to locate ScsiBusDev\r
-// structure in the SCSIBusDriverBindingStop(). Then we can\r
-// Close all opened protocols and release this structure.\r
-//\r
-EFI_GUID  mScsiBusProtocolGuid = EFI_SCSI_BUS_PROTOCOL_GUID;\r
-\r
 VOID  *mWorkingBuffer;\r
 \r
 /**\r
@@ -79,6 +71,49 @@ NotifyFunction (
   IN  VOID       *Context\r
   );\r
 \r
+/**\r
+  Allocates an aligned buffer for SCSI device.\r
+\r
+  This function allocates an aligned buffer for the SCSI device to perform\r
+  SCSI pass through operations. The alignment requirement is from SCSI pass\r
+  through interface.\r
+\r
+  @param  ScsiIoDevice      The SCSI child device involved for the operation.\r
+  @param  BufferSize        The request buffer size.\r
+\r
+  @return A pointer to the aligned buffer or NULL if the allocation fails.\r
+\r
+**/\r
+VOID *\r
+AllocateAlignedBuffer (\r
+  IN SCSI_IO_DEV              *ScsiIoDevice,\r
+  IN UINTN                    BufferSize\r
+  )\r
+{\r
+  return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), ScsiIoDevice->ScsiIo.IoAlign);\r
+}\r
+\r
+/**\r
+  Frees an aligned buffer for SCSI device.\r
+\r
+  This function frees an aligned buffer for the SCSI device to perform\r
+  SCSI pass through operations.\r
+\r
+  @param  Buffer            The aligned buffer to be freed.\r
+  @param  BufferSize        The request buffer size.\r
+\r
+**/\r
+VOID\r
+FreeAlignedBuffer (\r
+  IN VOID                     *Buffer,\r
+  IN UINTN                    BufferSize\r
+  )\r
+{\r
+  if (Buffer != NULL) {\r
+    FreeAlignedPages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));\r
+  }\r
+}\r
+\r
 /**\r
   The user Entry Point for module ScsiBus. The user code starts with this function.\r
 \r
@@ -174,6 +209,15 @@ SCSIBusDriverBindingSupported (
     // if yes, return EFI_SUCCESS.\r
     //\r
     if ((RemainingDevicePath == NULL) || IsDevicePathEnd (RemainingDevicePath)) {\r
+      //\r
+      // Close protocol regardless of RemainingDevicePath validation\r
+      //\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiExtScsiPassThruProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );      \r
       return EFI_SUCCESS;\r
     } else {\r
       //\r
@@ -297,6 +341,15 @@ SCSIBusDriverBindingStart (
     return DevicePathStatus;\r
   }\r
 \r
+  //\r
+  // Report Status Code to indicate SCSI bus starts\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_SCSI | EFI_IOB_PC_INIT),\r
+    ParentDevicePath\r
+    );  \r
+\r
   //\r
   // To keep backward compatibility, UEFI ExtPassThru Protocol is supported as well as \r
   // EFI PassThru Protocol. From priority perspective, ExtPassThru Protocol is firstly\r
@@ -380,7 +433,7 @@ SCSIBusDriverBindingStart (
     // \r
     Status = gBS->InstallProtocolInterface (\r
                     &Controller,\r
-                    &mScsiBusProtocolGuid,\r
+                    &gEfiCallerIdGuid,\r
                     EFI_NATIVE_INTERFACE,\r
                     &ScsiBusDev->BusIdentify\r
                     );\r
@@ -394,7 +447,7 @@ SCSIBusDriverBindingStart (
     //\r
     Status = gBS->OpenProtocol (\r
                     Controller,\r
-                    &mScsiBusProtocolGuid,\r
+                    &gEfiCallerIdGuid,\r
                     (VOID **) &BusIdentify,\r
                     This->DriverBindingHandle,\r
                     Controller,\r
@@ -407,6 +460,15 @@ SCSIBusDriverBindingStart (
     ScsiBusDev = SCSI_BUS_CONTROLLER_DEVICE_FROM_THIS (BusIdentify);\r
   }\r
 \r
+  //\r
+  // Report Status Code to indicate detecting devices on bus\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_SCSI | EFI_IOB_PC_DETECT),\r
+    ParentDevicePath\r
+    );\r
+\r
   Lun  = 0;\r
   if (RemainingDevicePath == NULL) {\r
     //\r
@@ -420,11 +482,14 @@ SCSIBusDriverBindingStart (
     // only scan the specified device by RemainingDevicePath\r
     //\r
     if (ScsiBusDev->ExtScsiSupport) {\r
-      ScsiBusDev->ExtScsiInterface->GetTargetLun (ScsiBusDev->ExtScsiInterface, RemainingDevicePath, &TargetId, &Lun);  \r
+      Status = ScsiBusDev->ExtScsiInterface->GetTargetLun (ScsiBusDev->ExtScsiInterface, RemainingDevicePath, &TargetId, &Lun);  \r
     } else {\r
-      ScsiBusDev->ScsiInterface->GetTargetLun (ScsiBusDev->ScsiInterface, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun);\r
+      Status = ScsiBusDev->ScsiInterface->GetTargetLun (ScsiBusDev->ScsiInterface, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun);\r
     }\r
 \r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
   } else {\r
     //\r
     // If RemainingDevicePath is the End of Device Path Node,\r
@@ -548,7 +613,7 @@ SCSIBusDriverBindingStop (
     //\r
     Status = gBS->OpenProtocol (\r
                     Controller,\r
-                    &mScsiBusProtocolGuid,\r
+                    &gEfiCallerIdGuid,\r
                     (VOID **) &Scsidentifier,\r
                     This->DriverBindingHandle,\r
                     Controller,\r
@@ -566,7 +631,7 @@ SCSIBusDriverBindingStop (
     //\r
     gBS->UninstallProtocolInterface (\r
            Controller,\r
-           &mScsiBusProtocolGuid,\r
+           &gEfiCallerIdGuid,\r
            &ScsiBusDev->BusIdentify\r
            );\r
 \r
@@ -781,6 +846,15 @@ ScsiResetBus (
 \r
   ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
 \r
+  //\r
+  // Report Status Code to indicate reset happens\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
+    ScsiIoDevice->ScsiBusDeviceData->DevicePath\r
+    );\r
+\r
   if (ScsiIoDevice->ExtScsiSupport){\r
     return ScsiIoDevice->ExtScsiPassThru->ResetChannel (ScsiIoDevice->ExtScsiPassThru);\r
   } else {\r
@@ -810,6 +884,16 @@ ScsiResetDevice (
   UINT8        Target[TARGET_MAX_BYTES];\r
 \r
   ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
+\r
+  //\r
+  // Report Status Code to indicate reset happens\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
+    ScsiIoDevice->ScsiBusDeviceData->DevicePath\r
+    );\r
+  \r
   CopyMem (Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
 \r
 \r
@@ -902,13 +986,35 @@ ScsiExecuteSCSICommand (
 \r
   if (ScsiIoDevice->ExtScsiSupport) {\r
     ExtRequestPacket = (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *) Packet;\r
-    Status = ScsiIoDevice->ExtScsiPassThru->PassThru (\r
-                                          ScsiIoDevice->ExtScsiPassThru,\r
-                                          Target,\r
-                                          ScsiIoDevice->Lun,\r
-                                          ExtRequestPacket,\r
-                                          Event\r
-                                          );\r
+\r
+    if (((ScsiIoDevice->ExtScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO) != 0) && (Event !=  NULL)) {\r
+      Status = ScsiIoDevice->ExtScsiPassThru->PassThru (\r
+                                                ScsiIoDevice->ExtScsiPassThru,\r
+                                                Target,\r
+                                                ScsiIoDevice->Lun,\r
+                                                ExtRequestPacket,\r
+                                                Event\r
+                                                );\r
+    } else {\r
+      //\r
+      // If there's no event or the SCSI Device doesn't support NON-BLOCKING,\r
+      // let the 'Event' parameter for PassThru() be NULL.\r
+      //\r
+      Status = ScsiIoDevice->ExtScsiPassThru->PassThru (\r
+                                                ScsiIoDevice->ExtScsiPassThru,\r
+                                                Target,\r
+                                                ScsiIoDevice->Lun,\r
+                                                ExtRequestPacket,\r
+                                                NULL\r
+                                                );\r
+      if ((!EFI_ERROR(Status)) && (Event != NULL)) {\r
+        //\r
+        // Signal Event to tell caller to pick up the SCSI IO packet if the\r
+        // PassThru() succeeds.\r
+        //\r
+        gBS->SignalEvent (Event);\r
+      }\r
+    }\r
   } else {\r
 \r
     mWorkingBuffer = AllocatePool (sizeof(EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
@@ -934,7 +1040,7 @@ ScsiExecuteSCSICommand (
       //\r
       Status = gBS->CreateEvent (\r
                        EVT_NOTIFY_SIGNAL,\r
-                       TPL_CALLBACK,\r
+                       TPL_NOTIFY,\r
                        NotifyFunction,\r
                        &EventData,\r
                        &PacketEvent\r
@@ -968,7 +1074,7 @@ ScsiExecuteSCSICommand (
                                           ScsiIoDevice->Pun.ScsiId.Scsi,\r
                                           ScsiIoDevice->Lun,\r
                                           mWorkingBuffer,\r
-                                          Event\r
+                                          NULL\r
                                           );\r
       if (EFI_ERROR(Status)) {\r
         FreePool(mWorkingBuffer);\r
@@ -981,6 +1087,13 @@ ScsiExecuteSCSICommand (
       // free mWorkingBuffer.\r
       //\r
       FreePool(mWorkingBuffer);\r
+\r
+      //\r
+      // Signal Event to tell caller to pick up the SCSI IO Packet.\r
+      //\r
+      if (Event != NULL) {\r
+        gBS->SignalEvent (Event);\r
+      }\r
     }\r
   }\r
   return Status;\r
@@ -1014,13 +1127,67 @@ ScsiScanCreateDevice (
   EFI_STATUS                Status;\r
   SCSI_IO_DEV               *ScsiIoDevice;\r
   EFI_DEVICE_PATH_PROTOCOL  *ScsiDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;\r
+  EFI_HANDLE                 DeviceHandle;\r
+\r
+  DevicePath          = NULL;\r
+  RemainingDevicePath = NULL;\r
+  ScsiDevicePath      = NULL;\r
+  ScsiIoDevice        = NULL;\r
+\r
+  //\r
+  // Build Device Path\r
+  //\r
+  if (ScsiBusDev->ExtScsiSupport){\r
+    Status = ScsiBusDev->ExtScsiInterface->BuildDevicePath (\r
+                                             ScsiBusDev->ExtScsiInterface,\r
+                                             &TargetId->ScsiId.ExtScsi[0],\r
+                                             Lun,\r
+                                             &ScsiDevicePath\r
+                                             );\r
+  } else {\r
+    Status = ScsiBusDev->ScsiInterface->BuildDevicePath (\r
+                                          ScsiBusDev->ScsiInterface,\r
+                                          TargetId->ScsiId.Scsi,\r
+                                          Lun,\r
+                                          &ScsiDevicePath\r
+                                          );\r
+  }\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  DevicePath = AppendDevicePathNode (\r
+                 ScsiBusDev->DevicePath,\r
+                 ScsiDevicePath\r
+                 );\r
+\r
+  if (DevicePath == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
+  }\r
+\r
+  DeviceHandle = NULL;\r
+  RemainingDevicePath = DevicePath;\r
+  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);\r
+  if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {\r
+    //\r
+    // The device has been started, directly return to fast boot.\r
+    //\r
+    Status = EFI_ALREADY_STARTED;\r
+    goto ErrorExit;\r
+  }\r
 \r
   ScsiIoDevice = AllocateZeroPool (sizeof (SCSI_IO_DEV));\r
   if (ScsiIoDevice == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
   }\r
 \r
   ScsiIoDevice->Signature                 = SCSI_IO_DEV_SIGNATURE;\r
+  ScsiIoDevice->ScsiBusDeviceData         = ScsiBusDev;\r
   CopyMem(&ScsiIoDevice->Pun, TargetId, TARGET_MAX_BYTES);\r
   ScsiIoDevice->Lun                       = Lun;\r
 \r
@@ -1041,52 +1208,21 @@ ScsiScanCreateDevice (
   ScsiIoDevice->ScsiIo.ResetDevice        = ScsiResetDevice;\r
   ScsiIoDevice->ScsiIo.ExecuteScsiCommand = ScsiExecuteSCSICommand;\r
 \r
-\r
-  if (!DiscoverScsiDevice (ScsiIoDevice)) {\r
-    FreePool (ScsiIoDevice);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
   //\r
-  // Set Device Path\r
+  // Report Status Code here since the new SCSI device will be discovered\r
   //\r
-  ScsiDevicePath = NULL;\r
-  if (ScsiIoDevice->ExtScsiSupport){\r
-    Status = ScsiIoDevice->ExtScsiPassThru->BuildDevicePath (\r
-                                          ScsiIoDevice->ExtScsiPassThru,\r
-                                          &ScsiIoDevice->Pun.ScsiId.ExtScsi[0],\r
-                                          ScsiIoDevice->Lun,\r
-                                          &ScsiDevicePath\r
-                                          );\r
-  } else {\r
-    Status = ScsiIoDevice->ScsiPassThru->BuildDevicePath (\r
-                                          ScsiIoDevice->ScsiPassThru,\r
-                                          ScsiIoDevice->Pun.ScsiId.Scsi,\r
-                                          ScsiIoDevice->Lun,\r
-                                          &ScsiDevicePath\r
-                                          );\r
-  }\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_SCSI | EFI_IOB_PC_ENABLE),\r
+    ScsiBusDev->DevicePath\r
+    );\r
 \r
-  if (EFI_ERROR(Status)) {\r
-    FreePool (ScsiIoDevice);\r
-    return Status;\r
+  if (!DiscoverScsiDevice (ScsiIoDevice)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
   }\r
 \r
-  ScsiIoDevice->DevicePath = AppendDevicePathNode (\r
-                              ScsiBusDev->DevicePath,\r
-                              ScsiDevicePath\r
-                              );\r
-  //\r
-  // The memory space for ScsiDevicePath is allocated in\r
-  // ScsiPassThru->BuildDevicePath() function; It is no longer used\r
-  // after EfiAppendDevicePathNode,so free the memory it occupies.\r
-  //\r
-  FreePool (ScsiDevicePath);\r
-\r
-  if (ScsiIoDevice->DevicePath == NULL) {\r
-    FreePool (ScsiIoDevice);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
+  ScsiIoDevice->DevicePath = DevicePath;\r
 \r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &ScsiIoDevice->Handle,\r
@@ -1097,31 +1233,48 @@ ScsiScanCreateDevice (
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    FreePool (ScsiIoDevice->DevicePath);\r
-    FreePool (ScsiIoDevice);\r
-    return EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
   } else {\r
     if (ScsiBusDev->ExtScsiSupport) {\r
       gBS->OpenProtocol (\r
-            Controller,\r
-            &gEfiExtScsiPassThruProtocolGuid,\r
-            (VOID **) &(ScsiBusDev->ExtScsiInterface),\r
-            This->DriverBindingHandle,\r
-            ScsiIoDevice->Handle,\r
-            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-            );\r
+             Controller,\r
+             &gEfiExtScsiPassThruProtocolGuid,\r
+             (VOID **) &(ScsiBusDev->ExtScsiInterface),\r
+             This->DriverBindingHandle,\r
+             ScsiIoDevice->Handle,\r
+             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+             );\r
      } else {\r
       gBS->OpenProtocol (\r
-            Controller,\r
-            &gEfiScsiPassThruProtocolGuid,\r
-            (VOID **) &(ScsiBusDev->ScsiInterface),\r
-            This->DriverBindingHandle,\r
-            ScsiIoDevice->Handle,\r
-            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-            );\r
+             Controller,\r
+             &gEfiScsiPassThruProtocolGuid,\r
+             (VOID **) &(ScsiBusDev->ScsiInterface),\r
+             This->DriverBindingHandle,\r
+             ScsiIoDevice->Handle,\r
+             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+             );\r
      }\r
   }\r
   return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+  \r
+  //\r
+  // The memory space for ScsiDevicePath is allocated in\r
+  // ScsiPassThru->BuildDevicePath() function; It is no longer used\r
+  // after AppendDevicePathNode,so free the memory it occupies.\r
+  //\r
+  FreePool (ScsiDevicePath);\r
+\r
+  if (DevicePath != NULL) {\r
+    FreePool (DevicePath);\r
+  }\r
+\r
+  if (ScsiIoDevice != NULL) {\r
+    FreePool (ScsiIoDevice);\r
+  }\r
+\r
+  return Status;\r
 }\r
 \r
 \r
@@ -1144,64 +1297,89 @@ DiscoverScsiDevice (
   UINT8                 SenseDataLength;\r
   UINT8                 HostAdapterStatus;\r
   UINT8                 TargetStatus;\r
-  EFI_SCSI_SENSE_DATA   SenseData;\r
-  EFI_SCSI_INQUIRY_DATA InquiryData;\r
+  EFI_SCSI_INQUIRY_DATA *InquiryData;\r
+  UINT8                 MaxRetry;\r
+  UINT8                 Index;\r
+  BOOLEAN               ScsiDeviceFound;\r
 \r
   HostAdapterStatus = 0;\r
   TargetStatus      = 0;\r
+\r
+  InquiryData = AllocateAlignedBuffer (ScsiIoDevice, sizeof (EFI_SCSI_INQUIRY_DATA));\r
+  if (InquiryData == NULL) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
+  }\r
+\r
   //\r
   // Using Inquiry command to scan for the device\r
   //\r
   InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);\r
-  SenseDataLength   = sizeof (EFI_SCSI_SENSE_DATA);\r
-\r
-  Status = ScsiInquiryCommand (\r
-            &ScsiIoDevice->ScsiIo,\r
-            EFI_TIMER_PERIOD_SECONDS (1),\r
-            (VOID *) &SenseData,\r
-            &SenseDataLength,\r
-            &HostAdapterStatus,\r
-            &TargetStatus,\r
-            (VOID *) &InquiryData,\r
-            &InquiryDataLength,\r
-            FALSE\r
-            );\r
-  if (EFI_ERROR (Status) && Status != EFI_BAD_BUFFER_SIZE) {\r
-    return FALSE;\r
+  SenseDataLength   = 0;\r
+  ZeroMem (InquiryData, InquiryDataLength);\r
+\r
+  MaxRetry = 2;\r
+  for (Index = 0; Index < MaxRetry; Index++) {\r
+    Status = ScsiInquiryCommand (\r
+              &ScsiIoDevice->ScsiIo,\r
+              SCSI_BUS_TIMEOUT,\r
+              NULL,\r
+              &SenseDataLength,\r
+              &HostAdapterStatus,\r
+              &TargetStatus,\r
+              (VOID *) InquiryData,\r
+              &InquiryDataLength,\r
+              FALSE\r
+              );\r
+    if (!EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    if ((Status == EFI_BAD_BUFFER_SIZE) ||\r
+        (Status == EFI_INVALID_PARAMETER) ||\r
+        (Status == EFI_UNSUPPORTED)) {\r
+      ScsiDeviceFound = FALSE;\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  if (Index == MaxRetry) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
   }\r
+  \r
   //\r
   // Retrieved inquiry data successfully\r
   //\r
-  if ((InquiryData.Peripheral_Qualifier != 0) &&\r
-      (InquiryData.Peripheral_Qualifier != 3)) {\r
-    return FALSE;\r
+  if (InquiryData->Peripheral_Qualifier != 0) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
   }\r
 \r
-  if (InquiryData.Peripheral_Qualifier == 3) {\r
-    if (InquiryData.Peripheral_Type != 0x1f) {\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  if (0x1e >= InquiryData.Peripheral_Type && InquiryData.Peripheral_Type >= 0xa) {\r
-    return FALSE;\r
+  if (0x1e >= InquiryData->Peripheral_Type && InquiryData->Peripheral_Type >= 0xa) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
   }\r
 \r
   //\r
   // valid device type and peripheral qualifier combination.\r
   //\r
-  ScsiIoDevice->ScsiDeviceType  = InquiryData.Peripheral_Type;\r
-  ScsiIoDevice->RemovableDevice = InquiryData.Rmb;\r
-  if (InquiryData.Version == 0) {\r
+  ScsiIoDevice->ScsiDeviceType  = InquiryData->Peripheral_Type;\r
+  ScsiIoDevice->RemovableDevice = InquiryData->Rmb;\r
+  if (InquiryData->Version == 0) {\r
     ScsiIoDevice->ScsiVersion = 0;\r
   } else {\r
     //\r
     // ANSI-approved version\r
     //\r
-    ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData.Version & 0x03);\r
+    ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData->Version & 0x07);\r
   }\r
 \r
-  return TRUE;\r
+  ScsiDeviceFound = TRUE;\r
+\r
+Done:\r
+  FreeAlignedBuffer (InquiryData, sizeof (EFI_SCSI_INQUIRY_DATA));\r
+\r
+  return ScsiDeviceFound;\r
 }\r
 \r
 \r