]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
when remaining device path is not NULL, check if it's the device managed by bus driver.
[mirror_edk2.git] / MdeModulePkg / Bus / Scsi / ScsiBusDxe / ScsiBus.c
index d53fdc8eb38f433bb3eb7c742cc9b7664b23d607..eaa4658e35813e8c0f670d8e095ff8bc07802345 100644 (file)
@@ -2,7 +2,7 @@
   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 - 2009, Intel Corporation. <BR>\r
+Copyright (c) 2006 - 2010, Intel Corporation. <BR>\r
 All rights reserved. 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
@@ -145,81 +145,101 @@ SCSIBusDriverBindingSupported (
   EFI_STATUS                      Status;\r
   EFI_SCSI_PASS_THRU_PROTOCOL     *PassThru;\r
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtPassThru;\r
-  EFI_DEV_PATH                    *Node;\r
+  UINT64                          Lun;\r
+  UINT8                           *TargetId;\r
+  SCSI_TARGET_ID                  ScsiTargetId;\r
 \r
-  if (RemainingDevicePath != NULL) {\r
-    Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
+  TargetId = &ScsiTargetId.ScsiId.ExtScsi[0];\r
+  SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);\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
+  // tried to open on host controller handle. If fails, then PassThru Protocol is tried instead.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiExtScsiPassThruProtocolGuid,\r
+                  (VOID **)&ExtPassThru,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+\r
+  if (Status == EFI_ALREADY_STARTED) {\r
+    return EFI_SUCCESS;\r
+  } else if (!EFI_ERROR(Status)) {\r
     //\r
-    // Check if RemainingDevicePath is the End of Device Path Node, \r
-    // if yes, go on checking other conditions\r
+    // Check if RemainingDevicePath is NULL or the End of Device Path Node,\r
+    // if yes, return EFI_SUCCESS.\r
     //\r
-    if (!IsDevicePathEnd (Node)) {\r
+    if ((RemainingDevicePath == NULL) || IsDevicePathEnd (RemainingDevicePath)) {\r
+      //\r
+      // Close protocol regardless of RemainingDevicePath validation\r
       //\r
-      // If RemainingDevicePath isn't the End of Device Path Node,\r
-      // check its validation\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiExtScsiPassThruProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );      \r
+      return EFI_SUCCESS;\r
+    } else {\r
+      //\r
+      // If RemainingDevicePath isn't the End of Device Path Node, check its validation\r
+      //\r
+      Status = ExtPassThru->GetTargetLun (ExtPassThru, RemainingDevicePath, &TargetId, &Lun);\r
       //\r
-      if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||\r
-          Node->DevPath.SubType != MSG_SCSI_DP ||\r
-          DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {\r
-        return EFI_UNSUPPORTED;\r
+      // Close protocol regardless of RemainingDevicePath validation\r
+      //\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiExtScsiPassThruProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );      \r
+      if (!EFI_ERROR(Status)) {\r
+        return EFI_SUCCESS;\r
       }\r
     }\r
   }\r
 \r
   //\r
-  // Check for the existence of Extended SCSI Pass Thru Protocol and SCSI Pass Thru Protocol\r
+  // Come here in 2 condition: \r
+  // 1. ExtPassThru doesn't exist.\r
+  // 2. ExtPassThru exists but RemainingDevicePath is invalid.\r
   //\r
   Status = gBS->OpenProtocol (\r
                   Controller,\r
-                  &gEfiExtScsiPassThruProtocolGuid,\r
-                  (VOID **)&ExtPassThru,\r
+                  &gEfiScsiPassThruProtocolGuid,\r
+                  (VOID **)&PassThru,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
-\r
+  \r
   if (Status == EFI_ALREADY_STARTED) {\r
     return EFI_SUCCESS;\r
   }\r
-\r
+  \r
   if (EFI_ERROR (Status)) {\r
-    Status = gBS->OpenProtocol (\r
-                    Controller,\r
-                    &gEfiScsiPassThruProtocolGuid,\r
-                    (VOID **)&PassThru,\r
-                    This->DriverBindingHandle,\r
-                    Controller,\r
-                    EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                    );\r
-\r
-    if (Status == EFI_ALREADY_STARTED) {\r
-      return EFI_SUCCESS;\r
-    }\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-    gBS->CloseProtocol (\r
-      Controller,\r
-      &gEfiScsiPassThruProtocolGuid,\r
-      This->DriverBindingHandle,\r
-      Controller\r
-      );\r
-    return EFI_SUCCESS;\r
+    return Status;\r
   }\r
-\r
+  \r
   //\r
-  // Close the I/O Abstraction(s) used to perform the supported test\r
+  // Test RemainingDevicePath is valid or not.\r
   //\r
+  if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {\r
+    Status = PassThru->GetTargetLun (PassThru, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun);\r
+  }\r
+  \r
   gBS->CloseProtocol (\r
-    Controller,\r
-    &gEfiExtScsiPassThruProtocolGuid,\r
-    This->DriverBindingHandle,\r
-    Controller\r
-    );\r
-\r
-  return EFI_SUCCESS;\r
+         Controller,\r
+         &gEfiScsiPassThruProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
+  return Status;\r
 }\r
 \r
 \r
@@ -259,25 +279,20 @@ SCSIBusDriverBindingStart (
   EFI_STATUS                            DevicePathStatus;\r
   EFI_STATUS                            PassThruStatus;\r
   SCSI_BUS_DEVICE                       *ScsiBusDev;\r
-  SCSI_TARGET_ID                        *ScsiTargetId;\r
+  SCSI_TARGET_ID                        ScsiTargetId;\r
   EFI_DEVICE_PATH_PROTOCOL              *ParentDevicePath;\r
   EFI_SCSI_PASS_THRU_PROTOCOL           *ScsiInterface;\r
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL       *ExtScsiInterface;\r
   EFI_SCSI_BUS_PROTOCOL                 *BusIdentify;\r
 \r
   TargetId        = NULL;\r
-  ScsiTargetId    = NULL;\r
   ScanOtherPuns   = TRUE;\r
   FromFirstTarget = FALSE;\r
   ExtScsiSupport  = FALSE;\r
   PassThruStatus  = EFI_SUCCESS;\r
   \r
-  ScsiTargetId = AllocateZeroPool(sizeof(SCSI_TARGET_ID));\r
-  if (ScsiTargetId == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  TargetId = &ScsiTargetId->ScsiId.ExtScsi[0];\r
+  TargetId = &ScsiTargetId.ScsiId.ExtScsi[0];\r
+  SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);\r
   \r
   DevicePathStatus = gBS->OpenProtocol (\r
                             Controller,\r
@@ -407,20 +422,21 @@ SCSIBusDriverBindingStart (
     // If RemainingDevicePath is NULL, \r
     // must enumerate all SCSI devices anyway\r
     //\r
-    SetMem (ScsiTargetId, TARGET_MAX_BYTES,0xFF);\r
     FromFirstTarget = TRUE;\r
-\r
   } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
     //\r
     // If RemainingDevicePath isn't the End of Device Path Node, \r
     // 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
@@ -438,7 +454,7 @@ SCSIBusDriverBindingStart (
       if (ScsiBusDev->ExtScsiSupport) {\r
         Status = ScsiBusDev->ExtScsiInterface->GetNextTargetLun (ScsiBusDev->ExtScsiInterface, &TargetId, &Lun);\r
       } else {\r
-        Status = ScsiBusDev->ScsiInterface->GetNextDevice (ScsiBusDev->ScsiInterface, &ScsiTargetId->ScsiId.Scsi, &Lun);\r
+        Status = ScsiBusDev->ScsiInterface->GetNextDevice (ScsiBusDev->ScsiInterface, &ScsiTargetId.ScsiId.Scsi, &Lun);\r
       }\r
       if (EFI_ERROR (Status)) {\r
         //\r
@@ -453,11 +469,11 @@ SCSIBusDriverBindingStart (
     // Avoid creating handle for the host adapter.\r
     //\r
     if (ScsiBusDev->ExtScsiSupport) {\r
-      if ((ScsiTargetId->ScsiId.Scsi) == ScsiBusDev->ExtScsiInterface->Mode->AdapterId) {\r
+      if ((ScsiTargetId.ScsiId.Scsi) == ScsiBusDev->ExtScsiInterface->Mode->AdapterId) {\r
         continue;\r
       }\r
     } else {\r
-      if ((ScsiTargetId->ScsiId.Scsi) == ScsiBusDev->ScsiInterface->Mode->AdapterId) {\r
+      if ((ScsiTargetId.ScsiId.Scsi) == ScsiBusDev->ScsiInterface->Mode->AdapterId) {\r
         continue;\r
       }\r
     }\r
@@ -465,9 +481,8 @@ SCSIBusDriverBindingStart (
     // Scan for the scsi device, if it attaches to the scsi bus,\r
     // then create handle and install scsi i/o protocol.\r
     //\r
-    Status = ScsiScanCreateDevice (This, Controller, ScsiTargetId, Lun, ScsiBusDev);\r
+    Status = ScsiScanCreateDevice (This, Controller, &ScsiTargetId, Lun, ScsiBusDev);\r
   }\r
-  FreePool (ScsiTargetId);\r
   return EFI_SUCCESS;\r
 \r
 ErrorExit:\r